Loading ...

Select distinct records from a collection | CodeAsp.Net

Select distinct records from a collection

 /5
0 (0votes)

Today my teammate had a requirement to select distinct records from a collection.  He was getting duplicate records in his collection; the collection was made of objects of a class having a number of properties. Now his goal was to select distinct records only out of those duplicate records. I decided to go for a custom comparer for this purpose and with the help of custom comparer along with LINQ I gave him the solution.  Below is the sample code:

Code of the Person class (This is the class on whose objects collection the distinct is needed )

 

#region Using Directives

using System;

#endregion

public class Person
{
    /// <summary>
    /// Gets or sets the user ID.
    /// </summary>
    /// <value>The user ID.</value>
    public Int32 UserID
    { get; set; }

    /// <summary>
    /// Gets or sets the name of the user.
    /// </summary>
    /// <value>The name of the user.</value>
    public String UserName
    { get; set; }


    /// <summary>
    /// Gets or sets the password.
    /// </summary>
    /// <value>The password.</value>
    public String Password
    { get; set; }
}





Sample class which is playing with the collection of person class objects:

 

 

#region Using Directives

using System;
using System.Collections.ObjectModel;

#endregion

public class Example
{

    public static void Main()
    {
        var persons = new Collection<Person>
        {
            new Person {UserID = 1, UserName = "UserName1",Password = "Password1"},
            new Person {UserID = 1, UserName = "UserName1",Password = "Password1"},
            new Person {UserID = 1, UserName = "UserName1",Password = "Password1"},
            new Person {UserID = 2, UserName = "UserName2",Password = "Password2"},
            new Person {UserID = 2, UserName = "UserName2",Password = "Password3"},
            new Person {UserID = 3, UserName = "UserName3",Password = "Password3"},
            new Person {UserID = 3, UserName = "UserName3",Password = "Password3"}
        };
        foreach (var person in persons)
        {
            Console.WriteLine("UserID:{0} , UserName:{1}",person.UserID,person.UserName);
        }
        Console.ReadLine();
    }

}



 


As you saw above in the code that users are getting repeated. So when you will run the above code you will see this output:


UserID:1 , UserName:UserName1
UserID:1 , UserName:UserName1
UserID:1 , UserName:UserName1
UserID:2 , UserName:UserName2
UserID:2 , UserName:UserName2
UserID:3 , UserName:UserName3
UserID:3 , UserName:UserName3

Now our goal is to select the distinct records only .
Solution:
I made a custom comparer class for it Named PersonComparer which implements IEqualityComparer <T> interface .
From MSDN: http://msdn.microsoft.com/en-us/library/ms132151.aspx


This interface allows the implementation of customized equality comparison for collections. That is, you can create your own definition of equality for type T, and specify that this definition be used with a collection type that accepts the IEqualityComparer<T> generic interface.

Below is code for PersonComparer class :

#region Using Directives

using System.Collections.Generic;

#endregion

public class PersonComparer : IEqualityComparer<Person>
{
   
    bool IEqualityComparer<Person>.Equals(Person x, Person y)
    {
        // Reference same
        if (ReferenceEquals(x, y)) return true;

        if (ReferenceEquals(x, null) || ReferenceEquals(y, null))
            return false;

        return x.UserID == y.UserID;
    }

    int IEqualityComparer<Person>.GetHashCode(Person person)
    {
        return person.UserID.GetHashCode();
    }
}




Above I am comparing based on UserID. Now lets modify the code which was playing with the collection:


#region Using Directives

using System;
using System.Collections.ObjectModel;
using System.Linq;

#endregion

public class Example
{

    public static void Main()
    {
        var persons = new Collection<Person>
        {
            new Person {UserID = 1, UserName = "UserName1",Password = "Password1"},
            new Person {UserID = 1, UserName = "UserName1",Password = "Password1"},
            new Person {UserID = 1, UserName = "UserName1",Password = "Password1"},
            new Person {UserID = 2, UserName = "UserName2",Password = "Password2"},
            new Person {UserID = 2, UserName = "UserName2",Password = "Password3"},
            new Person {UserID = 3, UserName = "UserName3",Password = "Password3"},
            new Person {UserID = 3, UserName = "UserName3",Password = "Password3"}
        };

        //Select Distinct

        foreach (var person in persons.Distinct(new PersonComparer()))
        {
            Console.WriteLine("UserID:{0} , UserName:{1}",person.UserID,person.UserName);
        }
        Console.ReadLine();
    }

}





Output:

 


UserID:1 , UserName:UserName1
UserID:2 , UserName:UserName2
UserID:3 , UserName:UserName3


Above the heart of the code is at .Distinct(new PersonComparer())) .
Distinct is the extension method from LINQ which accepts  System.Collections.Generic.IEqualityComparer<TSource>  comparer which is PersonComparer in this case. That’s it we are done , you can make your own custom comparer in this way for your own custom requirement.

Do let me know you feedback, comments

Comments (no comments yet)

Top Posts