2010-01-25 19 views
6

Quiero agrupar elementos de una consulta linq bajo un encabezado, de modo que para cada encabezado tengo una lista de objetos que coinciden con el título del encabezado. Supuse que la solución sería usar ToDictionary para convertir los objetos, pero esto permite solo un objeto por "grupo" (o clave de diccionario). Supuse que podía crear el diccionario de tipo (String, List Of()), pero no puedo descifrar cómo escribirlo.¿Cómo uso Linq ToDictionary para devolver un diccionario con valores múltiples en los ítems del diccionario?

Como ejemplo, he escrito una versión simplificada a continuación.

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 

El error es el siguiente

'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)'. 

¿Qué hago para dar salida a una lista para cada elemento del diccionario?

Respuesta

13

se podía primer grupo toda su resultado por su nombre y luego llamar a dictionnary con la clave de grupo como la clave

no sé cómo el código en VB, pero lo que se vería como en C#

Dictionary<string,List<Order>> dict = orders 
    .GroupBy(x => x.Name) 
    .ToDictionary(gr => gr.Key,gr=>gr.ToList()); 
+5

Dim f = d.GroupBy (Función (x) x.PoolName) .ToDictionary (Función (t) t.Key, Función (g) g.ToList()) - ¡Lo intentaré! – digiguru

+0

Esto funcionó como un sueño, gracias – digiguru

4

En lugar de ToDictionary, quiere ToLookup. Una búsqueda almacenará una lista de valores para cada clave, por lo que ya no se requiere que la clave sea única. La búsqueda devuelta por este método es inmutable.

+0

La idea es tener varios elementos para cada clave, por lo que la intención es tenerlo como único. ¿Es una búsqueda enumerable? – digiguru

+0

Sí, como la enumeración sobre groupsas mencionados en la documentación: http://msdn.microsoft.com/en-us/library/bb460184.aspx No es exactamente lo que hace la solución aceptada, pero está construido en función de: orders.ToLookup (x => x.Name, x => x); –

Cuestiones relacionadas