Click here to Skip to main content
15,893,790 members
Articles / Programming Languages / C#
Alternative
Tip/Trick

Diff two lists

Rate me:
Please Sign up or sign in to vote.
4.00/5 (1 vote)
15 Dec 2010CPOL 8.8K   1   5
/// /// 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)


Written By
Software Developer (Senior)
Belgium Belgium
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralOk, I get your point, and submitted another version, with on... Pin
Eskern15-Dec-10 21:25
Eskern15-Dec-10 21:25 
Generalif you have 2 lists with 2 elements each, you call that sele... Pin
cechode14-Dec-10 17:26
cechode14-Dec-10 17:26 
if you have 2 lists with 2 elements each, you call that selector 8 times
GeneralThe selector is only executed when the properties are access... Pin
Eskern14-Dec-10 9:35
Eskern14-Dec-10 9:35 
Generali was gonna diss it for the amount of times the selector get... Pin
cechode14-Dec-10 9:24
cechode14-Dec-10 9:24 
GeneralEDIT: code block formatted correctly. Pin
DaveAuld14-Dec-10 4:35
professionalDaveAuld14-Dec-10 4:35 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.