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

Diff two lists

4.00/5 (1 vote)
15 Dec 2010CPOL 9.1K  
/// /// Takes the difference between 2 collections/// public static DiffResult DiffWith( this IEnumerable first, IEnumerable second, Func keySelector) where T : new(){ return new DiffResult(first, second, keySelector);}public class...
C#
/// <summary>
/// Takes the difference between 2 collections
/// </summary>
public static DiffResult<T, P> DiffWith<T, P>(
    this IEnumerable<T> first, IEnumerable<T> second, Func<T, P> keySelector)
    where T : new()
{
     return new DiffResult<T, P>(first, second, keySelector);
}

C#
public class DiffResult<T, P>
    where T : new()
{
    private IEnumerable<T> _first = null;
            private IEnumerable<T> _second = null;
            private Func<T, P> _keySelector = null;
            private Lazy<P[]> _keysInFirst = null;
            private Lazy<P[]> _keysInSecond = null;
            private Lazy<Dictionary<P, T>> _resolvedFirst = null;
            private Lazy<Dictionary<P, T>> _resolvedSecond = null;
            public DiffResult(IEnumerable<T> first, IEnumerable<T> second, Func<T, P> keySelector)
            {
                _keySelector = keySelector;
                _first = first;
                _second = second;
                _resolvedFirst = new Lazy<Dictionary<P, T>>(() => { return _first.ToDictionary(_keySelector, x => x); });
                _resolvedSecond = new Lazy<Dictionary<P, T>>(() => { return _second.ToDictionary(_keySelector, x => x); });
                _keysInFirst = new Lazy<P[]>(() => { return _resolvedFirst.Value.Keys.ToArray(); });
                _keysInSecond = new Lazy<P[]>(() => { return _resolvedSecond.Value.Keys.ToArray(); });
            }
            public P[] KeysToAdd { get { return _keysInSecond.Value.Where(x => !_keysInFirst.Value.Contains(x)).ToArray(); } }
            public P[] KeysToRemove { get { return _keysInFirst.Value.Where(x => !_keysInSecond.Value.Contains(x)).ToArray(); } }
            public P[] KeysToUpdate { get { return _keysInFirst.Value.Intersect(_keysInSecond.Value).ToArray(); } }
            public IEnumerable<T> ToAdd { get { return _resolvedSecond.Value.Where(x => KeysToAdd.Contains(x.Key)).Select(x => x.Value); } }
            public IEnumerable<T> ToRemove { get { return _resolvedFirst.Value.Where(x => KeysToRemove.Contains(x.Key)).Select(x => x.Value); } }
            public IEnumerable<T> ToUpdate { get { return _resolvedFirst.Value.Where(x => KeysToUpdate.Contains(x.Key)).Select(x => x.Value
); } }
}

License

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