My question is about comparing List<string> with Dictionary <string, List<string>> using C# linq

Viewed 1364

I have referred the below link in stack-overflow for my requirement which provide the matching key and Boolean results.I need the result of keys and values from the dictionary which matches with list of string.

Referred Link below: Array with Dictionary in c# using Linq

The example is provided in the same link above. Any how I will provide the same below

Dictionary<int, List<string>> dict = new Dictionary<int, <string>>
{ 
    {1, new List<string>(){"A","B"}},
    {2, new List<string>(){"C","D"}},
    {3, new List<string>(){"G","H"}},
    {4, new List<string>(){"E","F"}},
    {5, new List<string>(){"I","J"}},
};

string[] values = new [] 
{
    "A", "D", "E"
};

var result = 
  from kvp in dict
  join s in values on kvp.Value equals s
select new {kvp.Key, Found = true};

What I tried is below:

var result = dict
  .Select(x => new { 
     keys = x.Key, 
     values = values
       .ToList()
       .Any(x.Value.Contains) 
   });

I Expect the output be like {1,A},{2,D},{4,E} but actually coming {1,True},{4,True},{5,True}

Could some one help me on this.

3 Answers

Technically, if you want, say, List<object> == {1, "A", 4, "D", 5, "E"};

I Expect the output be like {1,A,4,D,5,E}

you can try Where to filter out dict records and SelectMany to flatten them:

  Dictionary<int, string> dict = new Dictionary<int, string>() { 
    {1, new "A"},
    {2, new "B"},
    {3, new "c"},
    {4, new "D"},
    {5, new "E"},
  };

  string[] values = new [] {"A", "D", "E"};

  var result = dict
    .Where(pair => values.Contains(pair.Value))
    .SelectMany(pair => new object[] { pair.Key, pair.Value})
    .ToList();

  Console.Write(string.Join(", ", result));

Outcome:

  1, A, 4, D, 5, E

However, I doubt if you really want such strange data representation. A filtered collection (or dictionary) without SelectMany is more convenient:

  List<KeyValuePair<int, string>> result = dict
    .Where(pair => values.Contains(pair.Value))
    .ToList();

  Console.Write(string.Join(", ", result.Select(pair => $"{pair.Key}, {pair.Value}")));

Or

  Dictionary<int, string> result = dict
    .Where(pair => values.Contains(pair.Value))
    .ToDictionary(pair => pair.Key, pair => pair.value);

  Console.Write(string.Join(", ", result.Select(pair => $"{pair.Key}, {pair.Value}")));

Which produce the same outcome:

  1, A, 4, D, 5, E

Edit: Well, the problem's changed dramatically. Now we have

  Dictionary<int, List<string>> dict = new Dictionary<int, <string>>() { 
    {1, new List<string>() {"A", "B"}},
    {2, new List<string>() {"C", "D"}},
    {3, new List<string>() {"G", "H"}},
    {4, new List<string>() {"E", "F"}},
    {5, new List<string>() {"I", "J"}},
  };

  string[] values = new [] { "A", "D", "E" };

And we want filtered Dictionary<int, List<string>>:

  var result = dict
    .Select(pair => new {
      key = pair.Key,
      value = pair.Value.Intersect(values).ToList()
    })
    .Where(item => item.value.Any())
    .ToDictionary(item => item.key, item => item.value);

  Console.Write(string.Join(Environment.NewLine, result
    .Select(pair => $"{pair.Key} : [{string.Join(", ", pair.Value)}]"))); 

Outcome:

1 : [A]
2 : [D]
4 : [E]   

so, you basically want to select the key-value pairs in the dictionary where the values are in the 'values' array, right?

Something like this:

(from kvp in dict
 where values.Contains(kvp.Value)
 select kvp).ToDictionary(key => kvp.Key, value => kvp.Value);

Should work, but I can't test it right now.

Check this code

Dictionary<int, string> dict = new Dictionary<int, 
string>
 { 
  {1, "A"},
  {2, "B"},
  {3, "c"},
  {4, "D"},
  {5, "E"},
 };

 string[] values = new [] 
 {
   "A", "D", "E"
 };

Here you want just select dict which contains values of dict.

write linq like this:

var query=dict.Where(x=>values.Contains(x.Value));

So you get output like below:

[1, A]
[4, D]
[5, E]

For more please check this

Related