I have a list of objects within another list. It looks like this:
Dim _elements as List(Of List(Of Element))
- _elements(0) is a list of Element1, Element2, etc.
- _elements(1) is a list of Element5, Element6, etc.
I need to create a dictionary of the elements so that the index of each list is the Key in the dictionary. The value of the dictionary should hold all elements of the Legend type that can be found in the list. Something like the following:
Dim legendElements As New Dictionary(Of Integer, List(Of Element))
' Initialize the list in the dictionary
For i As Integer = 0 To _elements.Count - 1
legendElements(i) = new List(Of Element)
Next
For i As Integer = 0 To _elements.Count - 1
For each element as Element in _elements(i)
If element.GetType() Is GetType(Legend) Then
legendElements.add(element)
End If
Next
Next
Is there a System.Linq function that can do the equivalent as the example above?
CodePudding user response:
Call Enumerable.SelectMany
method to get a flatten list of the target type which you filter by calling the Enumerable.Where
method. Call the Enumerable.Select
method to create from the result IEnumerable
of anonymous objects to hold and pass the Legend
objects along with their indices, and finally, call the Enumerable.ToDictionary
method to create
Dictionary(Of Integer, Element)
from the anonymous objects.
Dim legendElements As Dictionary(Of Integer, Element) = elements.
SelectMany(Function(x) x.Where(Function(y) y.GetType Is GetType(Legend))).
Select(Function(v, k) New With {Key .Key = k, .Value = v}).
ToDictionary(Function(a) a.Key, Function(a) a.Value)
Do the proper cast if you need a Dictionary(Of Integer, Legend)
.
Dim legendElements As Dictionary(Of Integer, Legend) = elements.
SelectMany(Function(x) x.Where(Function(y) y.GetType Is GetType(Legend))).
Select(Function(v, k) New With {Key .Key = k, .Value = v}).
ToDictionary(Function(a) a.Key, Function(a) DirectCast(a.Value, Legend))