C# : How to compare Dictionary Values?

2019-07-20 21:44发布

问题:

I have a Dictionary<String,String> as follows

 Dictionary<String, String> MyDict = new Dictionary<String, String>();

and which contains

 MyDict.Add("A", "1010");
 MyDict.Add("B", "1011");
 MyDict.Add("C", "1110");
 MyDict.Add("D", "1010");
 MyDict.Add("E", "1011");
 MyDict.Add("F", "1010");

I need to Compare the Dictionary Values and then to add the keys which all having same values

here is My resulting Dictionary

 Dictionary<String, List<String>> MyResultDict = new Dictionary<String, List<String>>();

And My code

 var XXX = MyDict.ToLookup(X => X.Value, X => X.Key);
 MyResultDict = MyDict.ToDictionary(X => X.Key, X => XXX[X.Value].ToList());

The above code will produce the result like

 { "A"     { "A" , "D", "F" } }
 { "B"     { "B" , "E" } }
 { "C"     { "C" } }
 { "D"     { "A" , "D", "F" } }
 { "E"     { "B" , "E" } }
 { "F"     { "A" , "D", "F" } }

But my solution is having two problem

  1. There exist Duplicate value list ( for the keys D , E and F.)

  2. The Value List includes the key.

The Expected OutPut is like

 { "A"     { "D", "F" } }
 { "B"     { "E" } }

i.e There is no need of key C because C's value is not repeated anywhere.

and there is no need to include keys D , E and F because its already included in A's and B's value lists.

How to do this using Linq or Lambda Expression?

回答1:

Dictionary<string, List<string>> result = myDict
    .GroupBy(kvp => kvp.Value)
    .Select(grp => new { Key = grp.First().Key, Matches = grp.Skip(1).Select(k => k.Key).ToList() })
    .Where(m => m.Matches.Count > 0)
    .ToDictionary(m => m.Key, m => m.Matches);

or possibly a bit simpler:

Dictionary<string, List<string>> result = myDict
    .GroupBy(kvp => kvp.Value)
    .Where(grp => grp.Count() > 1)
    .ToDictionary(grp => grp.First().Key, grp => grp.Skip(1).Select(k => k.Key).ToList());


回答2:

This should do it:

var MyResultDict =
    MyDict
    .GroupBy(e => e.Value)
    .Where(g => g.Count() > 1)
    .ToDictionary(
        g => g.First().Key,
        g => g.Select(e => e.Key).Skip(1).ToList());

The key here (if you'll forgive the pun) is the GroupBy method - it collects together elements of an enumeration based on your comparison. Once you've done that, it's a simple case of removing the singletons and converting the remaining elements to a new Dictionary.



标签: c# linq lambda