5

I want to get different of n numbers of dictionaries using a lambda expression:

Dictionary<string, string> d1 = new Dictionary<string, string>();
d1.Add("Joe", "2, Barfield Way");
d1.Add("Mike", "17, Apollo Avenue");
d1.Add("Jane", "69, Lance Drive");


Dictionary<string, string> d2 = new Dictionary<string, string>();
d2.Add("Joe", "2, Barfield Way");
d2.Add("Jane", "69, Lance Drive");
// var diff = d1.Except(d2);

Let say I want to get the difference of two above dictionaries var diff = d1.Except(d2);

Now I want to get the same out using lambda expression for N numbers of dictionaries.

For an instant, I have merged two dictionaries into one. I want to get a difference of two dictionaries using lambda expression or any other LINQ expression.

Dictionary<string, Dictionary<string, string>> d = new Dictionary<string, Dictionary<string, string>>();
d.Add("Test", d1);
d.Add("Test2", d2);

I have tried the expression below but could not get any results.

d.Select(c => c.Value.Except(c.Value))
Salah Akbari
  • 39,330
  • 10
  • 79
  • 109
  • If you feel an answer solved your problem, please don't forget to mark it as accepted by clicking the gray check mark beside the answer https://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work/5235#5235 – Salah Akbari Jan 16 '20 at 10:44

4 Answers4

4

You need some Linq methods:

var result = d.SelectMany(d => d.Value).GroupBy(c => c.Key)
              .Where(c => c.Count() == 1).ToDictionary(t => t.Key, t => t.Select(c => c.Value)
              .FirstOrDefault()).ToList();
Salah Akbari
  • 39,330
  • 10
  • 79
  • 109
  • @MarcoSalerno It can be easily changed to `c => new { c.Key, c.Value }` then, however I doubt whether single column grouping or multiple column grouping is what the OP are looking for, maybe we need more clarification from his side, BTW this link could be a good reference on multi-col grouping https://stackoverflow.com/a/38434457/2946329 – Salah Akbari Jan 10 '20 at 16:28
1

Convert it to a collection of KeyValuePair<> enumerables and follow the same logic using .Aggregate()

var result = d.Select(x => x.Value.AsEnumerable()).Aggregate((x, y) => x.Except(y));
Innat3
  • 3,561
  • 2
  • 11
  • 29
0

You can store the Dictionaries in a List<Dictionary<string, string>>.

Then query this collection and group by the keys , filter by count of key to get the unique ones only, then build a new Dictionary :

var d1 = new Dictionary<string, string>
{
    { "Joe", "2, Barfield Way" },
    { "Mike", "17, Apollo Avenue" },
    { "Jane", "69, Lance Drive" }
};

var d2 = new Dictionary<string, string>
{
    { "Joe", "2, Barfield Way" },
    { "foo", "bar" },
    { "Jane", "69, Lance Drive" }
};

var d3 = new Dictionary<string, string>
{
    { "hello", "world" },
    { "foo", "bar" }
};

var dicts = new List<Dictionary<string, string>>
{
    d1,
    d2,
    d3
};

var distinct = dicts.SelectMany(d => d)          // Flatten the collection of dictionaries
                    .GroupBy(d => d.Key)         // Group the sequence by key
                    .Where(d => d.Count() == 1)  // Filter the result for unique keys only
                    .ToDictionary(k => k.Key, v => v.Select(x => x.Value)
                                                    .First()); // Materialize the sequence in a Dictionary<string, string>

foreach (var key in distinct.Keys)
{
    Console.WriteLine($"{key} -> {distinct[key]}");
}

Output is

Mike -> 17, Apollo Avenue
hello -> world
Cid
  • 14,968
  • 4
  • 30
  • 45
0

This way you will get the same result:

Dictionary<string, string> d1 = new Dictionary<string, string>();
d1.Add("Joe", "2, Barfield Way");
d1.Add("Mike", "17, Apollo Avenue");
d1.Add("Jane", "69, Lance Drive");

Dictionary<string, string> d2 = new Dictionary<string, string>();
d2.Add("Joe", "2, Barfield Way");
d2.Add("Jane", "69, Lance Drive");

var diff = d1.Except(d2);

Dictionary<string, Dictionary<string, string>> d = new Dictionary<string, Dictionary<string, string>>();
d.Add("Test", d1);
d.Add("Test2", d2);

var diff1 = d.SelectMany(x => x.Value).GroupBy(x => new { x.Key, x.Value }).Where(x => x.Count() == 1).SelectMany(x => x.AsEnumerable());
Marco Salerno
  • 5,131
  • 2
  • 12
  • 32