Selecione um dicionário <T1, T2> com LINQ

171

Eu usei o método "select" de palavra-chave e extensão para retornar um IEnumerable<T>com LINQ, mas preciso retornar um genérico Dictionary<T1, T2>e não consigo descobrir. O exemplo que aprendi usando algo de uma forma semelhante à seguinte:

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

Eu também fiz a mesma coisa com métodos de extensão. Eu assumi que, como os itens em um Dictionary<T1, T2>podem ser iterados, KeyValuePair<T1, T2>eu poderia substituir "SomeClass" no exemplo acima por " new KeyValuePair<T1, T2> { ...", mas isso não funcionou (Key e Value foram marcados como somente leitura, portanto, não pude compilar esse código )

Isso é possível ou preciso fazer isso em várias etapas?

Obrigado.

Rico
fonte

Respostas:

284

Os métodos de extensões também fornecem uma extensão ToDictionary . É bastante simples de usar, o uso geral é passar um seletor lambda para a chave e obter o objeto como o valor, mas você pode passar um seletor lambda para a chave e o 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);

Então objectDictionary[1]conteria o valor "Olá"

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

Supondo que SomeClass.prop1seja o desejado Keypara o dicionário.

Albertein
fonte
27
.ToDictionary(item => item.prop1, item => item.prop2);explicitamente também definir o valor.
finoutlook
42

Uma coleção de KeyValuePairé ainda mais explícita e executa muito bem.

Dictionary<int, string> dictionary = objects
    .Select(x=> new KeyValuePair<int, string>(x.Id, x.Name))
    .ToDictionary(x=>x.Key, x=>x.Value);
Antoine Meltzheim
fonte
É possível remover .ToDictionary (x => x.Key, x => x.Value); e substituir o novo KeyValuePair pelo novo dicionário?
Amir Hajiha
@ AmirNo-Family Você está enganado. O método Select (x => x ...) executa uma projeção para cada elemento dos objetos coleção . Portanto, substituir o novo KeyValuePair pelo novo dicicionário criaria um dicionário de dicionários. Eu não acho que é isso que você está buscando.
Antoine Meltzheim
Eu tenho uma lista de Dictionary <string, string> e estava tentando usar select neles, mas gera um erro de compilação.
Amir Hajiha