views:

567

answers:

2

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?

+1  A: 

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() );
Johnny Blaze
Dim f = d.GroupBy(Function(x) x.PoolName).ToDictionary(Function(t) t.Key, Function(g) g.ToList()) - I'll give it a go!
digiguru
This worked like a dream, thanks
digiguru
+2  A: 

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.

Chris
The idea is to have multiple items for each key, so the intention is to have it as unique. Is a Lookup Enumerable?
digiguru
Yes, it as enumeration over groupsas mentioned in the documentation: http://msdn.microsoft.com/en-us/library/bb460184.aspxIt does exactly what the accepted solution does, but is a built in function: orders.ToLookup(x => x.Name, x => x);
Chris