Monday, March 31, 2014

Getting unique records based on property from list without using Distinct() in Linq

The scenario is very simple. We have a collection of Person objects. We want to know the unique PersonTypes from the collection. Below the Person class definition.

    public class Person
    {
        [Display(Name = "First Name")]
        public string PersonType { getset; }
        public XElement Properties { getset; }
    }
    public class PersonType
    {
        public string TypeName { getset; }
    }

I don't think nobody will write a loop to achieve this. The normal solution we may think of is to get the distinct Person objects using the Distinct function in Linq. But it requires an IEqualityComparer derived object to handle the comparison which is employed to find the duplicates by the Distinct function. I have explained about IEqualityComparer in one of my previous posts related to merging 2 collections without duplicates.

        static internal IEnumerable<PersonType> GetUniquePersonTypes()
        {
            IEnumerable<PersonType> personTypesList = _persons.Distinct(new PersonComparer())
                                                                                                .Select(per=>new PersonType(){TypeName=per.PersonType});
            return personTypesList;
        }
   public  class PersonComparer:IEqualityComparer<Person>
    {
        bool IEqualityComparer<Person>.Equals(Person person1, Person person2)
        {
            return person1.PersonType.Equals(person2.PersonType);
        }
 
        int IEqualityComparer<Person>.GetHashCode(Person person)
        {
            return person.PersonType.GetHashCode();
        }
    }

GroupBy to find distinct objects based on entity property

Should we really need Distinct and another class which implements IEqualityComparer? If we group the list based on the property which is key to decide duplicate and build a collection out of the group keys, won't that be same result of Distinct with comparer? Lets try it.

        static internal IEnumerable<PersonType> GetUniquePersonTypes()
        {
            IEnumerable<PersonType> personTypesList= _persons.GroupBy(x => x.PersonType)
                                                                                            .Select(group => new PersonType() 
                                                                                                                { TypeName = group.Key }
                                                                                            );
            return personTypesList;
        }

Is it working? Happy coding

No comments: