Friday, March 5, 2010

Linq Remove Duplicates and Merge Two Collections using Union and Distinct

Linq is a boon from Microsoft to all .net developers; it makes things really easy and simple and also gives the ability to perform several tasks that you do using sql (many more).I had to remove duplicates based on some columns from two different collections, it was done using for loops in the past, as linq is available I thought of giving it a shot.

Union and distinct is used to obtain the desired results; also notice a custom IEqualityComparer is passed to distinct instead of the default equality comparer to compare values. In custom equality comparer you can ignore the columns or properties you don’t want to consider when deciding the uniqueness. If you don’t have a custom IEqualityComparer then linq distinct wont work as expected and might return duplicates.

Let’s dive into some code here.
''define lists
Dim list1 As New List(Of Item)
Dim list2 As New List(Of Item)

''add two items to list 1
Dim item1 As New Item
item1.ItemID = Guid.Empty
item1.ItemName = "item1"


Dim item2 As New Item
item2.ItemID = Guid.Empty
item2.ItemName = "item2"


''add same item(item 2 from list1) to list 2
Dim item3 As New Item
item3.ItemID = Guid.Empty
item3.ItemName = "item1"


''get thee distinct of the two lists
Dim aaaaa = (From l1i In list1 Select l1i).Union _
(From l2i In list2 Select l2i).Distinct(New ItemComparer)

''a simple item class
Public Class Item
Public ItemID As Guid
Public ItemName As String
End Class

''custom IEqualityComparer for our item class
Public Class ItemComparer
Implements IEqualityComparer(Of Item)

Public Function Equals1(ByVal x As Item, ByVal y As Item) As Boolean _
Implements IEqualityComparer(Of Item).Equals

If x Is y Then Return True

If x Is Nothing OrElse y Is Nothing Then Return False

Return (x.ItemID = y.ItemID) AndAlso (x.ItemName = y.ItemName)

End Function

Public Function GetHashCode1(ByVal item As Item) As Integer _
Implements IEqualityComparer(Of Item).GetHashCode

If item Is Nothing Then Return 0

Dim hashname = _
If(item.ItemName Is Nothing, 0, item.ItemName.GetHashCode())

Dim hashid = item.ItemID.GetHashCode()

Return hashname Xor hashid
End Function
End Class

No comments:

Post a Comment