Reputation: 2153
In vb.net, using linq, join 2 list of object. Both list are the same type.
I search the best way to concat both list grouping by Id. Like a Distinct.
Sample :
Imports System.Text
Imports System.Reflection
Module Module1
Sub Main()
Dim list1 As New List(Of Item)
For i As Integer = 1 To 4
list1.Add(New Item(i, i.ToString))
Next
Dim list2 As New List(Of Item)
For i As Integer = 3 To 6
list2.Add(New Item(i, i.ToString))
Next
Dim list3 As New List(Of Item)
list3 = (list1.Concat(list2)).ToList
Console.WriteLine(Item.PrintList(list3).ToString)
Console.ReadLine()
End Sub
End Module
Class Item
Private _Id As Integer
Private _Value As String
Public Property Id() As Integer
Get
Return _Id
End Get
Set(ByVal value As Integer)
_Id = value
End Set
End Property
Public Property Value() As String
Get
Return _Value
End Get
Set(ByVal value As String)
_Value = value
End Set
End Property
Public Sub New()
End Sub
Public Sub New(ByVal id As Integer, ByVal value As String)
Me.Id = id
Me.Value = value
End Sub
Public Overrides Function ToString() As String
Dim sb = New Text.StringBuilder()
For Each item In [GetType]().GetFields(BindingFlags.NonPublic Or BindingFlags.Instance)
sb.Append(String.Format("[{0} = {1}] ", item.Name, item.GetValue(Me)))
Next
Return sb.ToString()
End Function
Public Shared Function PrintList(ByVal myList As List(Of Item)) As StringBuilder
Dim result As New StringBuilder
For Each i In myList
result.AppendLine(i.ToString)
Next
Return result
End Function
End Class
What the list3 contain after concat :
[_Id = 1] [_Value = 1]
[_Id = 2] [_Value = 2]
[_Id = 3] [_Value = 3]
[_Id = 4] [_Value = 4]
[_Id = 3] [_Value = 3]
[_Id = 4] [_Value = 4]
[_Id = 5] [_Value = 5]
[_Id = 6] [_Value = 6]
What we want :
[_Id = 1] [_Value = 1]
[_Id = 2] [_Value = 2]
[_Id = 3] [_Value = 3]
[_Id = 4] [_Value = 4]
[_Id = 5] [_Value = 5]
[_Id = 6] [_Value = 6]
Upvotes: 2
Views: 1631
Reputation: 11509
With the addition of Equals and GetHashCode in Tim Schmelter answer, you now also have the possibility to use Concat and .Distinct directly on the Query:
Dim list3 As List(Of Item) = list1.Concat(list2).Distinct.ToList
or using where and distinct in the query:
Dim list3 As List(Of Item) = (From data In list1.Concat(list2) Where data.Value = "MyCity" Distinct).ToList
variation:
Dim list3 As List(Of Item) = (From data In list1.Concat(list2) Where data.Value = "MyCity").Distinct.ToList
Upvotes: 1
Reputation: 460138
I search the best way to concat both list grouping by Id. Like a Distinct.
Use Enumerable.Union
.
However, you need to override Equals
and GetHashCode
in the class Item
first. Then all Linq methods will use your ID:
Class Item
Public Property ID As Int32
Public Overrides Function Equals(obj As Object) As Boolean
If obj Is Nothing Then Return False
If Not TypeOf obj Is Item Then Return False
Return Id = DirectCast(obj, Item).Id
End Function
Public Overrides Function GetHashCode() As Integer
Return Id.GetHashCode()
End Function
End Class
Now you can use Union
which is efficient and clear:
Dim list3 = list1.Union(list2).ToList
MSDN:
This method excludes duplicates from the return set. This is different behavior to the
Concat<TSource>
method, which returns all the elements in the input sequences including duplicates. ... To compare a custom data type, you need to implement this interface and provide your own GetHashCode and Equals methods for the type.
Upvotes: 4