TheBoubou
TheBoubou

Reputation: 19903

Get the differences between 2 lists

I have two lists (ListA and ListB), the type of these lists is the same PersonInfo, the Loginfield is a unique key.

public class PersonInfo
{
    public string Login { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int Age { get; set; }
    public bool Active { get; set; }
}

I'd like compare these two lists :

  1. I'd like get a list of items in ListA not available in ListB

  2. For the items available in both lists, I'd like get a list from ListA (Login field is a unique key) for the item where there is a difference between the two lists.

Example : if for the Login "MyLogin" in ListA, the value of FirstName does not match with the value in ListB. The item with "MyLogin" as Login must be part of the result list.

Example : if the Age between ListA and ListB for a specific login is different, the item must be part of the result

Thanks.

Upvotes: 3

Views: 23909

Answers (5)

Muneeb Zulfiqar
Muneeb Zulfiqar

Reputation: 1023

Try this for objects comparison and loop around it for List<T>

public static void GetPropertyChanges<T>(this T oldObj, T newObj)
{
    Type type = typeof(T);
    foreach (System.Reflection.PropertyInfo pi in type.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance))
    {
        object selfValue = type.GetProperty(pi.Name).GetValue(oldObj, null);
        object toValue = type.GetProperty(pi.Name).GetValue(newObj, null);
        if (selfValue != null && toValue != null)
        {
            if (selfValue.ToString() != toValue.ToString())
            {
                //do your code
            }
        }
    }
}

Upvotes: 0

Ahmed Elzeiny
Ahmed Elzeiny

Reputation: 67

var list3 = list1.Except(list2).ToList(); //List3 contains what in list1 but not _list2.

Upvotes: 2

Prashanth Thurairatnam
Prashanth Thurairatnam

Reputation: 4361

To compare objects of custom data type lists, you will need to implement IEquatable in your class and override GetHashCode()

Check this MSDN Link

Your class

    public class PersonInfo : IEquatable<PersonInfo>
    {
        public string Login { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int Age { get; set; }
        public bool Active { get; set; }

        public bool Equals(PersonInfo other)
        {
            //Check whether the compared object is null.
            if (Object.ReferenceEquals(other, null)) return false;

            //Check whether the compared object references the same data.
            if (Object.ReferenceEquals(this, other)) return true;

            //Check whether the properties are equal.
            return Login.Equals(other.Login) && FirstName.Equals(other.FirstName) && LastName.Equals(other.LastName) && Age.Equals(other.Age) && Active.Equals(other.Active);
        }

        public override int GetHashCode()
        {

            int hashLogin = Login == null ? 0 : Login.GetHashCode();

            int hashFirstName = FirstName == null ? 0 : FirstName.GetHashCode();

            int hashLastName = LastName == null ? 0 : LastName.GetHashCode();

            int hashAge = Age.GetHashCode();

            int hashActive = Active.GetHashCode();

            //Calculate the hash code.
            return (hashLogin + hashFirstName + hashLastName) ^ (hashAge + hashActive);
        }
    }

Then here is how you use it (as listed in Pranay's response)

            List<PersonInfo> ListA = new List<PersonInfo>() { new PersonInfo { Login = "1", FirstName = "James", LastName = "Watson", Active = true, Age = 21 }, new PersonInfo { Login = "2", FirstName = "Jane", LastName = "Morrison", Active = true, Age = 25 }, new PersonInfo { Login = "3", FirstName = "Kim", LastName = "John", Active = false, Age = 33 } };
            List<PersonInfo> ListB = new List<PersonInfo>() { new PersonInfo { Login = "1", FirstName = "James2222", LastName = "Watson", Active = true, Age = 21 }, new PersonInfo { Login = "3", FirstName = "Kim", LastName = "John", Active = false, Age = 33 } };

            //Get Items in ListA that are not in ListB
            List<PersonInfo> FilteredListA = ListA.Except(ListB).ToList();

            //To get the difference between ListA and FilteredListA (items from FilteredListA will be removed from ListA)
            ListA.RemoveAll(a => FilteredListA.Contains(a));

Upvotes: 5

Pranay Rana
Pranay Rana

Reputation: 176896

EDIT

Try this soltuion for detail difference : Compare two objects and find the differences


How to: Find the Set Difference Between Two Lists (LINQ)

Enumerable.Except Method (IEnumerable, IEnumerable) -Produces the set difference of two sequences by using the default equality comparer to compare values.

       double[] numbers1 = { 2.0, 2.1, 2.2, 2.3, 2.4, 2.5 };
        double[] numbers2 = { 2.2 };

        IEnumerable<double> onlyInFirstSet = numbers1.Except(numbers2);

or

//newList will include all the common data between the 2 lists
List<T> newList = list1.Intersect(list2).ToList<T>();


//differences will be the data not found 
List<T> differences = list1.RemoveAll(a => newList.Contains(a));

or

outer join to get difference

var compare1to2 = from a in 
           from b in driveList2.Where(b => b.property == a.property).DefaultIfEmpty()
                              select a;

Upvotes: 4

rt2800
rt2800

Reputation: 3045

you can use Zip() and Intersect() from LINQ

Upvotes: -4

Related Questions