Convert combo dictionary to IEnumerable

I have a dictionary:

Dictionary<String, List<Foo>> test = new Dictionary<String, List<Foo>>(); 

Then I populate this dictionary, so I need a list, so I can call Add (). My problem is to return the function:

 Dictionary<String, IEnumerable<Foo>> 

Is there any easy way to do this without doing the obvious and looping through the original dictionary and executing it manually?

+6
source share
3 answers

It is more efficient and convenient to use List<Foo> to add things, but add it to Dictionary<String, IEnumerable<Foo>> . This is not a problem, since List<Foo> implements IEnumerable<Foo> , it does not even need to be done.

So something like this (pseudo code):

 var test = new Dictionary<String, IEnumerable<Foo>>(); foreach(var x in something) { var list = new List<Foo>(); foreach(var y in x.SomeCollection) list.Add(y.SomeProperty); test.Add(x.KeyProperty, list); // works since List<T> is also an IEnumerable<T> } 
+1
source
 return dictionary.ToDictionary(x => x.Key,x => x.Value.AsEnumerable()) 
+4
source

I also tried this route, converting Dictionary<string, List<Foo>> to ReadOnlyDictionary<string, IEnumerable<Foo>> . Although I tried to convert to a read-only dictionary, the whole purpose of converting List to IEnumerable is to create a read-only collection. The problem with the OP approach:

 Dictionary<string, List<string>> errors = new Dictionary<string, List<string>>(); errors["foo"] = new List<string>() { "You can't do this" }; Dictionary<string, IEnumerable<string>> readOnlyErrors = // convert errors... readOnlyErrors["foo"] = new List<string>() { "I'm not actually read-only!" }; 

The appearance of IEnumerable<Foo> makes you think that it is only read and safe, but in fact it is not. After reading the LINQ Convert Dictionary to Lookup question, the Lookup object is more appropriate as it allows you to:

  • Associate one key with multiple values

  • You cannot overwrite a key with a new value

     // This results in a compiler error lookUp["foo"] = new List<Foo>() { ... }; 
  • Multiple Values ​​are already defined as IEnumerable<T>

  • You can use the same outer and inner loop algorithm to extract individual values:

     ILookup<string, string> lookup = // Convert to lookup foreach (IGrouping<string, string> grouping in lookup) { Console.WriteLine(grouping.Key + ":"); foreach (string item in grouping) { Console.WriteLine(" item: " + item); } } 

Convert Dictionary<string, List<Foo>> to ILookup<string, Foo>

This is a quick two-line:

 Dictionary<string, List<Foo>> foos = // Create and populate 'foos' ILookup<string, Foo> lookup = foos.SelectMany(item => item.Value, Tuple.Create) .ToLookup(p => p.Item1.Key, p => p.Item2); 

Now you can use the same two-step loop as Dictionary<string, IEnumerable<Foo>> :

 foreach (IGrouping<string, Foo> grouping in lookup) { string key = grouping.Key; foreach (Foo foo in grouping) { // Do stuff with key and foo } } 

Source: LINQ Convert Dictionary to Lookup

Converting to another dictionary using an IEnumerable value is like trying to impose a square anchor in a circular hole. A more suitable and safe way (from an object-oriented point of view) is to convert the read / write dictionary into a search query. This gives you the true perceived security of a read-only object (with the exception of Foo elements, which may not be immutable).

I would say that in most cases when ReadOnlyDictionary used, you can use ILookup and get the same functionality.

0
source

Source: https://habr.com/ru/post/982314/


All Articles