65.9K
CodeProject is changing. Read more.
Home

Diff two lists

starIconstarIconstarIconstarIconstarIcon

5.00/5 (2 votes)

Dec 10, 2010

CPOL
viewsIcon

5212

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;
}