Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I use Linq ToDictionary to return a dictionary with multiple values in the dictionary items?

I want to group items from a linq query under a header, so that for each header I have a list of objects that match the header title. I assumed the solution would be to use ToDictionary to convert the objects, but this allows only one object per "group" (or dictionary key). I assumed I could create the dictionary of type (String, List Of()), but I can't figure out how to write it.

As an example I have written a simplified version below.

Public Class order
    Public ID As Integer
    Public Name As String
    Public DateStamp As Date
End Class
Public Function GetOrdersSortedByDate() As Generic.Dictionary(Of String, Generic.List(Of User))
    Dim orders As New List(Of order)(New order() _
    {New order With _
     {.ID = 1, .Name = "Marble", .DateStamp = New Date(2010, 1, 1)}, _
     New order With _
     {.ID = 2, .Name = "Marble", .DateStamp = New Date(2010, 5, 1)}, _
     New order With _
     {.ID = 3, .Name = "Glass", .DateStamp = New Date(2010, 1, 1)}, _
     New order With _
     {.ID = 4, .Name = "Granite", .DateStamp = New Date(2010, 1, 1)}})

    ' Create a Dictionary that contains Package values, 
    ' using TrackingNumber as the key.
    Dim dict As Dictionary(Of String, List(Of order)) = _
        orders.ToDictionary(Of String, List(Of order))(Function(mykey) mykey.Name, AddressOf ConvertOrderToArray) ' Error on this line

    Return dict
End Function
Public Function ConvertOrderToArray(ByVal myVal As order, ByVal myList As Generic.List(Of order)) As Generic.List(Of order)
    If myList Is Nothing Then myList = New Generic.List(Of order)
    myList.Add(myVal)
    Return myList
End Function

The error is as follows

'Public Function ConvertOrderToArray(myVal As order, myList As System.Collections.Generic.List(Of order)) As System.Collections.Generic.List(Of order)'
does not have a signature compatible with delegate 
'Delegate Function Func(Of order, System.Collections.Generic.List(Of order))(arg As order) As System.Collections.Generic.List(Of order)'.

What do I do to output a list for each dictionary item?

like image 999
digiguru Avatar asked Jan 25 '10 19:01

digiguru


2 Answers

you could first group all your result by name and then call to dictionnary with the group key as key

i don't know how to code it in VB but what it would look like in C#

 Dictionary<string,List<Order>> dict = orders
  .GroupBy(x => x.Name)
  .ToDictionary(gr => gr.Key,gr=>gr.ToList() );
like image 157
Cheick Avatar answered Nov 04 '22 23:11

Cheick


Instead of ToDictionary, you want ToLookup. A lookup will store a list of values for each key, so the key is no longer required to be unique. The lookup returned from this method is immutable though.

like image 6
Chris Pitman Avatar answered Nov 04 '22 22:11

Chris Pitman