0

Good day all. I was looking through out the forums but have not found anything useful.

I have two custom lists and I need to display third list with differences.

list1[0].Id = 10;
list1[0].Name = "Peter";
list1[0].Age = 45;
list1[0].Group = "Group1";

list1[1].Id = 11;
list1[1].Name = "John";
list1[1].Age = 42;
list1[1].Group = "Group2";

list1[2].Id = 12;
list1[2].Name = "Mike";
list1[2].Age = 32;
list1[2].Group = "Group2";


list2[0].Id = 10;
list2[0].Name = "Peter";
list2[0].Age = 45;
list2[0].Group = "Group2";

list2[1].Id = 11;
list2[1].Name = "John";
list2[1].Age = 48;
list2[1].Group = "Group2";

list2[2].Id = 12;
list2[2].Name = "Mike";
list2[2].Age = 32;
list2[2].Group = "Group2";

I need to generate list 3 which will contain differences record with id 10 and id 11

mikola
  • 15
  • 6

3 Answers3

1

Before the answers get out of hand, let me post an answer specific to this question, but with method taken from:

https://stackoverflow.com/a/5636486/103139

Create the following two classes

public class Person{
    public int ID{ get; set;}
    public int Age{ get; set;}
    public string Name{ get; set;}
    public string Group{ get; set;}

    // constructors and other class specific 
    // methods come here.
}

public class PersonComparer : IEqualityComparer<Person>
{
    public int GetHashCode(Person p)
    {
        if (p == null)
        {
            return 0;
        }

        // you can put any custom hashcode generation here.
        return p.Name.GetHashCode() 
                    ^ p.Age.GetHashCode 
                    ^ p.Group.GetHashCode();

    }

    public bool Equals(Person p1, Person p1) {
        if (object.ReferenceEquals(p1, p2)) {
            return true;
        }
        if (
            object.ReferenceEquals(p1, null) ||
            object.ReferenceEquals(p2, null)
        ) {
            return false;
        }
        return p1.Name == p2.Name &&
                p1.Age == p2.Age &&
                p1.Group == p2.Group;   // consider equal ordinal ignore case
    }
}

Than in the place you have your lists do something along the lines of:

var diff = list1.Except(list2, new PersonComparer()).ToList();

Given that your lists are of List. Note that this does not include ID in the check, as I took from you OP example.

Community
  • 1
  • 1
bastijn
  • 5,841
  • 5
  • 27
  • 43
-2

var diff1 = list1.Where(p => list2.FirstOrDefault(q => (p.Age == q.Age && p.Group == q.Group && p.Id == q.Id && p.Name == q.Name)) == null).ToList();

        var diff2=list2.Where(p => list1.FirstOrDefault(q => (p.Age == q.Age && p.Group == q.Group && p.Id == q.Id && p.Name == q.Name)) == null).ToList();

        var diff = diff1.Concat(diff1).ToList();
M.S.
  • 4,283
  • 1
  • 19
  • 42
  • This is not the proper way. Consider what happens when you have lists with a large number of items. This will become very expensive. You are running through the other list for each item in the first list, and vice versa (worst case). – bastijn Jan 09 '14 at 12:40
  • This will work even if both the lists have different number of elements. In any case you have to iterate through each element. – M.S. Jan 09 '14 at 12:44
  • The key here is to understand that you have to visit them "at least once", and not as many times as items in the list. That is why Except is better. The Except extension method uses a HashSet internally for the second sequence passed in - that allows it to look up elements in O(1) while iterating over the first sequence to filter out elements that are contained in the second sequence, hence the overall effort is O(n+m) where n and m are the length of the input sequences - this is the best you can hope to do since you have to look at each element at least once. – bastijn Jan 09 '14 at 12:48
-2

Use class with properties ID,age,name and group

eg : class example{

                int Id;
                int age;
                string name;
                string group;

              }

create list of class

List <example> list1=new List<example>();

list1.Add(new example{Id=1,age=22,name="n1",group="g1"});

list1.Add(new example{Id=2,age=30,name="n2",group="g2"});

3rd list to take difference

list1.Add(new example{Id=list1[0].Id-list[1].Id,age=list1[0].age-list[1].age});

now your

list1[2] contains diff between liss1[0],list[1]

  • Apart from being shady code at the very least, this is not what the OP asks for. You are adding a 3rd item to list1 that is a person with age is age1-age2, and id = id1-id2. It makes no sense. – bastijn Jan 09 '14 at 12:53