Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

Diff two lists

5.00/5 (2 votes)
19 Dec 2010CPOL 5.2K  
I had the same problem, but Contains was a disaster waiting to happen. :(I ended up creating something like: //Lists is a list of 4 lists ( Added, Changed, Deleted , Unchanged )public static Lists Diff(List listA, List listB, IComparer PrimaryCompare, IComparer[]...
I had the same problem, but Contains was a disaster waiting to happen. :(
I ended up creating something like:

//Lists<T> is a list of 4 lists ( Added, Changed, Deleted , Unchanged )

public static Lists<T>  Diff<T>(List<T> listA, List<T> listB, IComparer<T> PrimaryCompare, IComparer[] SecondaryCompares) where T : IComparer
{
    var ret = new Lists<T>();
    int iOne = 0;
    int iTwo = 0;
    if (listB == null && listA == null){}
    else if (listA.Count < 1 && listB == null) { }
    else if (listA.Count < 1)
    {
        ret[States.Added].AddRange(listB);
    }
    else
    {
        PrimaryCompare = (PrimaryCompare == null) ? ((IComparer<T>)listA[0]) : PrimaryCompare;
        listA.Sort(PrimaryCompare);
        listB.Sort(PrimaryCompare);
        States state = States.None;
        while (iOne < listA.Count && iTwo < listB.Count)
        {
            switch (state = ProcessItem(listA[iOne], listB[iTwo], PrimaryCompare, ret, true))
            {
                case States.Added:
                    iTwo += 1;
                    break;
                case States.Deleted:
                    iOne += 1;
                    break;
                default:
                    if (SecondaryCompares != null)
                        ProcessAdditionalCompares(listA[iOne], listB[iTwo], SecondaryCompares, ret);
                    else
                        Add(listA[iOne], listB[iTwo], States.Unchanged, ret);
                    iOne += 1;
                    iTwo += 1;
                    break;
            }
        }
        AddRemainder(list1, ret, States.Deleted, iOne);
        AddRemainder(list2, ret, States.Added, iTwo);
    }
    return ret;
}

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)