Comment faire pour compter les occurrences de valeurs uniques dans le Dictionnaire?
J'ai un Dictionnaire avec des doubles que les valeurs et les chaînes de caractères comme des clés.
Je veux compter les occurrences de chaque valeur dans ce Dictionnaire, et je veux savoir cette valeur (ce qui est par exemple répétées).
par exemple:
key1, 2
key2, 2
key3, 3
key4, 2
key5, 5
key6, 5
Je veux obtenir une liste:
2 - 3 (times)
3 - 1 (once)
5 - 2 (twice)
Comment puis-je le faire?
Un peu plus d'infos: Êtes-vous demander à un nombre de valeurs qui ne sont pas répétés? Pourriez-vous nous donner un exemple de données, et de la sortie souhaitée?
Les tests en double pour l'égalité est un très pratique incertaine. Vous voudrez peut-être éviter de mentionner si vous voulez une réponse. À l'aide de Linq Distinct().Count() sur les Valeurs de la propriété est, par ailleurs, une approche qui correspondent à vos étiquettes.
Et comment voulez-vous tester l'Égalité de la double ici?
double possible de Valeurs Distinctes dans Dictionnaire<TKey,TValue>
non, ce n'est pas dupe de que question.
Les tests en double pour l'égalité est un très pratique incertaine. Vous voudrez peut-être éviter de mentionner si vous voulez une réponse. À l'aide de Linq Distinct().Count() sur les Valeurs de la propriété est, par ailleurs, une approche qui correspondent à vos étiquettes.
Et comment voulez-vous tester l'Égalité de la double ici?
double possible de Valeurs Distinctes dans Dictionnaire<TKey,TValue>
non, ce n'est pas dupe de que question.
OriginalL'auteur Patryk | 2011-12-10
Vous devez vous connecter pour publier un commentaire.
La première chose à noter, c'est que vous n'avez pas de soins sur les touches du dictionnaire. La première étape est donc de les ignorer comme non pertinentes pour la tâche à accomplir. Nous allons travailler avec le
Values
propriété du dictionnaire, et le travail est le même que pour toute autre collection d'entiers (ou tout autre énumérable de tout autre type, nous pouvons comparer pour l'égalité).Il y a deux méthodes courantes de ce problème, les deux sont bien la peine de savoir.
La première utilise un autre dictionnaire pour contenir le nombre de valeurs:
J'espère que c'est assez simple. Une autre approche est plus compliquée, mais a certains avantages:
(Nous aurions probablement utiliser
var
plutôt que de la verboseIEnumerable<IGrouping<int, int>>
, mais il vaut la peine d'être précis lors de l'explication de code).Dans une comparaison directe, cette version est inférieure à la fois plus complexe à comprendre et moins efficace. Cependant, l'apprentissage de cette approche permet une concis et efficace des variantes de la même technique, il est donc intéressant d'examiner.
GroupBy()
prend une énumération et crée une autre énumération qui contient des paires clé-valeur où la valeur est une énumération trop. Le lambdax => x
signifie que ce qu'il est regroupées par elle-même, mais nous avons la possibilité pour les différentes règles de regroupement que cela. Le contenu degrp
ressemble un peu à:Donc, si nous bouclons ce un pour chaque groupe, nous tirez le
Key
et appelCount()
sur le groupe, nous obtenons les résultats que nous voulons.Maintenant, dans le premier cas, nous avons construit notre comte dans un seul O(n) passe, alors qu'ici nous construisons le groupe en O(n) passe, et puis obtenir le comte dans un deuxième temps O(n) passe, ce qui la rend beaucoup moins efficace. C'est aussi un peu plus difficile à comprendre, alors, pourquoi la peine de le mentionner?
Bien, la première est que, une fois que nous comprenons cela, nous pouvons nous tourner les lignes:
Dans:
Qui est assez concis, et devient idiomatiques. Il est particulièrement agréable si on veut ensuite aller sur et faire quelque chose de plus compliqué avec la valeur-nombre de paires que nous pouvons chaîne dans une autre opération.
La version qui met les résultats dans un dictionnaire peut être encore plus concis encore:
Là, l'ensemble de votre réponse à la question dans une ligne courte, plutôt que le 6 (découpage des commentaires) pour la première version.
(Certains pourraient préférer remplacer
dict.Values.GroupBy(x => x)
avecdict.GroupBy(x => x.Value)
qui aura exactement les mêmes résultats, une fois que nous courons leCount()
sur elle. Si vous n'êtes pas sûr immédiatement pourquoi, essayer de s'en sortir).L'autre avantage, c'est que nous avons plus de flexibilité avec
GroupBy
dans les autres cas. Pour ces raisons, les gens qui sont habitués à l'aide deGroupBy
sont très susceptibles de commencer avec une ligne de la concision dedict.Values.GroupBy(x => x).ToDictinary(g => g.Key, g => g.Count());
et de changer pour le plus verbeux, mais plus effient forme de la première version (où on incrémente totaux en cours d'exécution dans le nouveau dictionnaire) si c'est une performance hotspot.OriginalL'auteur Jon Hanna
Même plus simple serait:
(Oui, c'est dans VB.NET mais vous ne devriez pas avoir trop de difficulté à se convertir à C# 🙂 )
OriginalL'auteur Eaglan Kurek