2

I have two List

List<List<KeyValuePair<string,string>>> List1;
List<List<KeyValuePair<string,string>>> List2;

I want to get a List>> List3, Which is the differnce of List1 and List2. Note: - Data is something like this:

List 1 -

         [{name, David},{eid,55},{sal,25}],
         [{name, Tina},{eid,56},{sal,20}],
         [{name, Bony},{eid,57},{sal,26}],
         [{name, Mahima},{eid,58},{sal,20}]

List 2 -

         [{name, David},{eid,55},{sal,25}],
         [{name, Tina},{eid,56},{sal,20}]    

As in the above lists we can see that there are two elements in List1 which are not available in List2, I want to get the list of those element.

Expected output: List3 -

         [{name, Bony},{eid,57},{sal,26}],
         [{name, Mahima},{eid,58},{sal,20}] 
SMT
  • 469
  • 1
  • 5
  • 17
  • 1
    Did you try anything? – MakePeaceGreatAgain Dec 01 '15 at 10:49
  • This is probably been answered already. Have a look [here](http://stackoverflow.com/a/7347402/706456) – oleksii Dec 01 '15 at 10:51
  • Possible duplicate of [Difference between two lists](http://stackoverflow.com/questions/5636438/difference-between-two-lists) – Rob Dec 01 '15 at 11:00
  • If you were to google "C# difference between lists", the second result is the question I marked this as a duplicate of. Please do *even some* research next time. – Rob Dec 01 '15 at 11:01

2 Answers2

2

You can use this approach:

List<List<KeyValuePair<string, string>>> List3 = List1
    .Where(l => !l.All(kv => List2.Any(l2 => l2.Contains(kv))))
    .ToList();

You can use Contains here because KeyValuePair<TKey, TValue> is a value type. If it was a class you would have to use Any and compare each key and value with each other (or override Equals+GetHashCode).

Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
1

perhaps one more idea. It is a list of a list of string keys and values, why not to use string comparison?

public class Comparer : IEqualityComparer<List<KeyValuePair<string, string>>>
{
    public static readonly Comparer Default = new Comparer();
    private Comparer() { }

    private static string KvpToString(KeyValuePair<string,string> kvp)
    {
        return (string.IsNullOrEmpty(kvp.Key) ? string.Empty : kvp.Key) + (string.IsNullOrEmpty(kvp.Value) ? string.Empty : kvp.Value);
    }
    public bool Equals(List<KeyValuePair<string, string>> x, List<KeyValuePair<string, string>> y)
    {
        var xx = x.Select(KvpToString).Aggregate((c, n) => c + n);
        var yy = y.Select(KvpToString).Aggregate((c, n) => c + n);
        return string.Compare(xx, yy) == 0;
    }
    public int GetHashCode(List<KeyValuePair<string, string>> obj)
    {
        return 0;
    }
}

So in the end, all its needs is:

var list3 = list1.Except(list2, Comparer.Default);

EDIT: Sorry, I copied previous version of Comparer, it was missing private constructor and Comparer.Default field. Now repaired...

ipavlu
  • 1,617
  • 14
  • 24