42 votes

Comment écrire une requête LINQ résultant dans un dictionnaire?

 
public class Person
{
    public string NickName{ get; set; }
    public string Name{ get; set; }
}

var pl = new List<Person>;

var q = from p in pl
        where p.Name.First() == 'A'
        orderby p.NickName
        select new KeyValuePair<String, String>(p.NickName, p.Name);

var d1 = q.ToList(); // Gives List<KeyValuePair<string, string>>
var d2 = q.ToDictionary(); // Does not compile
 

Comment obtenir Dictionary <string, string>?

43voto

Neil Knight Points 23759

Vous devez spécifier les valeurs pour les Dictionary

 var d2 = q.ToDictionary(p => p.NickName, p => p.Name);
 

11voto

Tim Schmelter Points 163781

Un dictionnaire ne peut pas contenir plusieurs clés égales, vous devez donc vous assurer (ou savoir) que ce n'est pas le cas. Vous pouvez utiliser GroupBy pour vous en assurer:

 Dictionary<string, string> dict = pl
        .Where(p => p.Name.First() == 'A')
        .GroupBy(p => p.NickName)
        .ToDictionary(g => g.Key, g => g.First().Name); 
 

7voto

Jodrell Points 14205

MODIFIER

Si vous vous sentez vraiment que vous devez obtenir à partir de IEnumerable<KeyValuePair<TKey, TValue>> d'un Dictionary implicitement vous pouvez ajouter cette extension.

public static IDictionary<TKey, ToValue> ToDictionary<TKey, TValue>(
    this IEnumerable<KeyValuePair<TKey, TValue>> source)
{
    return source.ToDictionary(p => p.Key, p => p.Value);
}

Vous pouvez ensuite appeler ToDictionary() sur tout IEnumerable<KeyValuePair<TKey, TValue>>.

EDIT 2

Si vous êtes en anticipant les doublons, vous pouvez créer une ToLookup() extension.

public static ILookup<TKey, TValue> ToLookup<TKey, TValue>(
    this IEnumerable<KeyValuePair<TKey, TValue>> source)
{
    return source.ToLookup(p => p.Key, p => p.Value);
}

Alternativement, si vous voulez vraiment jeter résultats, vous pouvez ajouter une surcharge pour l' ToDictionary.

public static IDictionary<TKey, ToValue> ToDictionary<TKey, TValue>(
    this IEnumerable<KeyValuePair<TKey, TValue>> source,
    Func<<IEnumerable<TValue>, TValue> selector)
{
    return source
        .Lookup(p => p.Key, p => p.Value);
        .ToDictionary(l => l.Key, l => selector(l));
}

Si vous arbitrairement jeter tout le mais la "première" (ça veut dire sans OrderBy) de l'élément, vous pouvez utiliser cette extension comme ceci,

pairs.ToDictionary(v => v.First()); 

Dans l'ensemble, vous pouvez supprimer la plupart de votre code et de le faire,

var q = from p in pl
        where p.Name.First() == 'A';
var d = q.ToDictionary(p => p.NickName, p => p.Name);

S'il pouvait y avoir des doublons, ne

var d = q.ToLookup(p => p.NickName, p => p.Name);

mais attention, il renvoie un ILookup<TKey, TElement>, l' Item indexeur qui renvoie une IEnumerable<TElement> de sorte que vous ne jetez pas de données.

5voto

Tilak Points 13095

Essayez de suivre pour NickName en tant que clé et Nom en tant que valeur

 var d2 = q.ToDictionary (p => p.NickName, p=>p.Name);
 

Mais notez que le dictionnaire n'autorise pas les doublons, c'est pourquoi, ci-dessus, une erreur sera générée pour les enregistrements en double portant le même surnom. Peut-être voudriez-vous utiliser Lookup qui est similaire à Dictionnaire, mais permet les doublons

 var d2 = q.ToLookup (p => p.NickName, p=>p.Name);
 

0voto

bhamby Points 8471

Je me rends compte que cela a été marqué avec , mais je littéralement juste essayer de comprendre comment faire cela dans hier, donc je pensais que je voudrais partager comment vous le faire en VB ainsi:

 Public Class Person
    Property NickName As String
    Property Name As String
End Class

Sub Main()
    Dim p1 As New List(Of Person)

    '*** Fill the list here ***

    Dim q = (From p In p1
             Where p.Name.First = "A"
             Select p.NickName, p.Name).ToDictionary(
                                           Function(k) k.NickName, 
                                           Function(v) v.Name)
End Sub
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X