12
votes

c # obtenir un sous-ensemble de valeur du dictionnaire de Keylist

OK, vous pouvez donc obtenir une valeur unique par dictionnaire [clé] ou toutes les valeurs par dictionnaire.values ​​.

Ce que je cherche, c'est un moyen Pour obtenir toutes les valeurs d'un jeu de clé donné, comme: xxx

avec xxx

bien sûr, je pouvais itérer manuellement The Keylist and user Dictionnaire [clé] à chaque fois et ajoutez toutes les valeurs à nouveau dans une liste, mais j'aimerais utiliser une manière plus élégante (par exemple, Linq).

Merci.


0 commentaires

6 Réponses :


20
votes

Essayez KEYS.Où (k => Dictionary.Containskey (k)). Sélectionnez (K => Dictionnaire [K]) . .


2 commentaires

Merci exactement ce que je cherchais.


Compiler dit que cela nécessite k => dans Sélectionner une instruction. La ligne devrait donc lire: clés.au (k => Dictionary.Containskey (k)). Sélectionnez (k => Dictionnaire [k]) .



2
votes
private List<object> GetValuesFromDictionaryUsingKeys(Dictionary<string, object> dictionary, List<string> keys)
{
    List<object> nList = new List<object>();

    foreach (string sKey in keys)
        if (dictionary.ContainsKey(sKey))
            nList.Add(dictionary[sKey]);

    return nList;         
}

2 commentaires

Notez que, le manque de bonté de Linq de côté, cela pénètre dans un dictionnaire et recherchez une liste - vous seriez beaucoup mieux de performance - sage dans la liste et recherchez le dictionnaire.


Si vous devez itérez, il serait préférable de créer la liste des clés plutôt que du dictionnaire. Il neutralise les avantages que le dictionnaire a une récupération rapide.



6
votes

Pourquoi écrire fonction lorsque vous pouvez avoir une méthode d'extension générique pour une utilisation quotidienne? XXX

EDIT: Que vous pouvez écrire: xxx


5 commentaires

Vous pouvez également utiliser ContainKey () comme Rawling a fait si vous n'êtes pas sûr que des clés existent.


Agréable. N'était pas au courant des méthodes d'extension génériques. Merci!


Nice, +1. Supprimer le Tolist () et il suffit de renvoyer le ienumerable et cela serait même plus agréable et linqy.


YAP, je suis retourné Liste parce que c'était requis Type de retour, mais cela est plus agréable.


Je veux juste souligner que si vous ne voulez pas que le sous-ensemble soit dupliqué, n'oubliez pas d'exécuter un .Distinct () sur les touches d'abord.



3
votes

Essayez: xxx

ou comme demandé: xxx

Utilisez .Intersect Pour supprimer les touches non présentes dans le dictionnaire, il est plus rapide qu'un .where (k => dictionary.containskey (k)) .

Supprimer l'instruction de .Intersect pour permettre élever un Exception pour une clé non trouvée dans le dictionnaire.


1 commentaires

Si je comprends bien, intersect utilise le comparateur d'égalité par défaut, ce qui peut ne pas être ce que vous voulez arriver. Par exemple, si vous initialisez votre dictionnaire comme suit: Nouveau dictionnaire (stringcomparer.ordinalignorecase), cela ne respecterait pas le comparateur.



1
votes

RAWLING Réponse fonctionne parfaitement, mais si vous connaissez au préalable, les clés existent sur le dictionnaire, cela peut être plus clair et efficace: clés.select (k => Dictionnaire [k])


0 commentaires

0
votes

Si vous recherchez une méthode d'extension haute performance (comparée aux autres réponses sur ce post) et éventuellement paresseuse, je vous suggère:

public static IEnumerable<V> ValuesFromIntersectedKeys<K, V>(this Dictionary<K, V> dic, IEnumerable<K> keys)
{
    V value;
    foreach (K k in keys)
    {
        if (dic.TryGetValue(k, out value))
            yield return value;
    }
}

public static IEnumerable<KeyValuePair<K, V>> IntersectKeys<K, V>(this Dictionary<K, V> dic, IEnumerable<K> keys)
{
    V value;
    foreach (K k in keys)
    {
        if (dic.TryGetValue(k, out value))
            yield return new KeyValuePair<K, V>(k, value);
    }
}


0 commentaires