Seleccione un diccionario <T1, T2> con LINQ

171

He usado la palabra clave "select" y el método de extensión para devolver un IEnumerable<T>mensaje con LINQ, pero necesito devolver un genérico Dictionary<T1, T2>y no puedo resolverlo. El ejemplo que aprendí de esto usó algo en una forma similar a la siguiente:

IEnumerable<T> coll = from x in y 
    select new SomeClass{ prop1 = value1, prop2 = value2 };

También hice lo mismo con los métodos de extensión. Supuse que, dado que los elementos en a Dictionary<T1, T2>se pueden KeyValuePair<T1, T2>iterar, simplemente podría reemplazar "SomeClass" en el ejemplo anterior con " new KeyValuePair<T1, T2> { ...", pero eso no funcionó (Key y Value se marcaron como de solo lectura, por lo que no pude compilar este código )

¿Es esto posible o debo hacerlo en varios pasos?

Gracias.

Rico
fuente

Respuestas:

284

Los métodos de extensiones también proporcionan una extensión ToDictionary . Es bastante simple de usar, el uso general es pasar un selector lambda para la clave y obtener el objeto como valor, pero puede pasar un selector lambda para clave y valor.

class SomeObject
{
    public int ID { get; set; }
    public string Name { get; set; }
}

SomeObject[] objects = new SomeObject[]
{
    new SomeObject { ID = 1, Name = "Hello" },
    new SomeObject { ID = 2, Name = "World" }
};

Dictionary<int, string> objectDictionary = objects.ToDictionary(o => o.ID, o => o.Name);

Entonces objectDictionary[1]contendría el valor "Hola"

Quintin Robinson
fuente
44
var dictionary = (from x in y 
                  select new SomeClass
                  {
                      prop1 = value1,
                      prop2 = value2
                  }
                  ).ToDictionary(item => item.prop1);

Eso suponiendo que SomeClass.prop1sea ​​lo deseado Keypara el diccionario.

alberteína
fuente
27
.ToDictionary(item => item.prop1, item => item.prop2);para explicitar establecer el valor también.
finoutlook
42

Una colección de KeyValuePaires aún más explícita y se ejecuta muy bien.

Dictionary<int, string> dictionary = objects
    .Select(x=> new KeyValuePair<int, string>(x.Id, x.Name))
    .ToDictionary(x=>x.Key, x=>x.Value);
Antoine Meltzheim
fuente
¿Es posible eliminar .ToDictionary (x => x.Key, x => x.Value); y reemplazar el nuevo KeyValuePair con un nuevo diccionario?
Amir Hajiha
@ AmirNo-Family Te estás equivocando. El método Select (x => x ...) realiza una proyección para cada elemento de la colección de objetos . Por lo tanto, reemplazar el nuevo KeyValuePair con un nuevo diccionario crearía un diccionario de diccionarios. No creo que sea a lo que estás apuntando.
Antoine Meltzheim
Tengo una lista de Dictionary <string, string> e intentaba usar select en ellos, pero arroja un error de compilación.
Amir Hajiha