Multi-touches dictionnaires (d'un autre genre) en C#?
Bâtiment sur cette question, est-il une solution simple pour avoir un multi-clés dictionnaire, où clé individuellement peut être utilisée pour identifier la valeur?
ie.
MultikeyDictionary<TKey1, TKey2, TValue> foo;
foo.Add(key1, key2, value);
myValue = foo[key1];
//value == myValue
foo.Remove(key2);
myValue = foo[key1]; //invalid, Exception or null returned
OriginalL'auteur Matthew Scharley | 2009-07-23
Vous devez vous connecter pour publier un commentaire.
Ce blog semble un détail plutôt décent mise en œuvre.
Je ne suis pas sûr de ce que nawfal est en train de parler, l'exemple ci-dessus est le plus rapide tout autour, mais voici une version mise à jour de tests de performance entre plusieurs "multi-touche" dictionnaire des implémentations: ici
Le lien est rompu.... a est la structure de la méthode?
Essayez ce lien (un cache de l'original): web.archive.org/web/20111209074636/http://www.aronweiler.com/...
Le lien doit pointer ici: fyslexicduck.com/2009/02/...
OriginalL'auteur Noldorin
Oui, définir une classe qui ajoute l'objet d'une table de hachage avec les deux touches,
(mais comme indiqué, vous ne pouvez pas utiliser les mêmes types avec cette mise en œuvre).
La deuxième
Remove
méthode n'est pas réalisable. Comment est laRemove
fait surkeyMap
dont les touches sontk1
, mais vous êtes en fournissantk2
? Bref, cette approche n'est pas complète.OriginalL'auteur Charles Bretana
Il n'y a rien de construit en .NET BCL pour ce type de collection pour le moment.
Je vois deux options:
Utiliser un dictionnaire. Le premier niveau des cartes différentes touches de la clé unique (GUID), et le deuxième niveau des cartes le GUID de la valeur réelle.
Créer une clé personnalisée de classe et d'implémenter Equals() et GetHashCode() de sorte qu'une composante de la clé est suffisante pour trouver la totalité de la clé. Vous pouvez ensuite d'approvisionnement en méthodes d'aide à construire des instances de la clé à l'aide de seulement l'une des valeurs de sorte que vous pourriez faire des recherches.
GetHashCode n'a pas besoin de retourner des valeurs, mais les valeurs ne doivent convenir avec vos Égaux valeurs. Votre objet pourrait juste retour 0, d'économiser beaucoup de temps de calcul, mais beaucoup de déchets lors de la collecte essaie d'utiliser votre (très) naïf code de hachage.
Je voudrais mettre en œuvre GetHashCode() à un peu de hachage de l'une des valeurs. Des codes de hachage n'avez pas à être unique (comme Matthieu identifie) - ils ont juste aider le dictionnaire de minimiser les collisions et ainsi affecter les performances.
1 n'est pas une bonne idée. Voir une discussion ici stackoverflow.com/a/1504548/661933. Je veux dire les plus performants sont les alternatives
OriginalL'auteur LBushkin
Une simple (et efficace) de la mise en œuvre serait d'utiliser PowerCollections'
Pair<TFirst, TSecond>
type comme une clé de dictionnaire, quelque chose commePaire<> met en œuvre
Equals
etGetHashCode
de façon constante, de sorte que vous n'avez pas besoin de recourir à plusieurs niveaux, les dictionnaires (qui sont de plus en plus lourde et probablement moins efficace).Il y a aussi un
Triple<TFirst, TSecond, TThird>
si vous avez besoin d'un 3-clé de dictionnaire.TValue
si je viens deTKey2
?Ceci ne répond pas à la question. La question demande un Dictionnaire qui récupère les valeurs par . Cette solution aurait toujours besoin de deux clés.
vous avez raison, ma réponse n'est pas pertinente.
OriginalL'auteur Igor Brejc
Je trouve beaucoup de réponses ici inutilement complexe, moins performante ou inutilisables. La meilleure approche serait d'avoir un
KeyValuePair<>
de la clé secondaire et la valeur sont cotisés comme leValue
de dictionnaires. Cela vous permet d'avoir juste une recherche pour l'enlèvement et la mise à jour des opérations. Une mise en œuvre directe:Quelques choses à noter:
J'ai mis en œuvre uniquement
IEnumerable<>
. Je ne pense pas queICollection<>
de sens ici, puisque la méthode noms de tous pourrait être de façon différente pour cette collection spéciale de la structure. À vous de décider de ce qui doit aller à l'intérieurIEnumerable<>
.J'ai tenté pour quelque étrange que des exceptions soient jetés ici et là - juste pour l'intégrité des données. Juste pour être sur le côté plus sûr de sorte que vous savez si jamais mon code a des bugs.
J'ai nommé les méthodes de telle manière que son compilable même lorsque
Key1
etKey2
sont du même type.Performance: Vous pouvez recherche pour
Value
, avec leKey
s.Get
etContains
méthode nécessite seulement 1 lookup (O(1)).Add
nécessite 2 recherches et 2 ajoute.Update
nécessite 1 de recherche et 2 ajoute.Remove
prend 3 recherches.OriginalL'auteur nawfal
Je l'ai essayé et il fonctionne parfaitement (inclure ajouter, supprimer & indexeur)
et même je l'a étendue à 4 valeurs:
Profiter,
Ofir
OriginalL'auteur Ofir
Sûr, c'est un langage OO et vous pouvez mettre en œuvre O vous voulez. Vous allez avoir une certaine ambiguïté à résoudre (si TKey1 et TKey2 sont du même type, les méthodes appelées alors?)
C'est une erreur de compilation: Tapez " Test<T1,T2>' définit déjà un membre appelé " x " avec les mêmes types de paramètres
OriginalL'auteur Amy B
Vous ne serez pas en mesure de définir les surcharges pour les deux types, et les génériques système ne permet pas pour un nombre arbitraire de types (type de méthodes qui permettent params). Donc, vous devez être coincé avec un ensemble de classes définies, 2, 3, 4, etc. simultanée des touches. En outre, vous devez utiliser l'objet en tant que paramètre pour obtenir et définir, à l'aide d'exécution type de contrôles pour simuler la surcharge.
En outre, vous ne stocker un dictionnaire de
<TKEY1,VAL>
, les autres dictionnaires serait de<TKEY2,TKEY1>
,<TKEY3,TKEY1>
et index dans le dictionnaire principal.C'est surtout de la chaudière de la plaque de code.
OriginalL'auteur Adam Luter
Vous pouvez trouver mon IndexMap mise en œuvre pour être une bonne base pour la réécriture de Java, en C#. Le modèle de programmation n'est pas aussi élégant que je préfère, mais il n'est pas destinée pour le développement avec directement. Plutôt, il se trouve derrière un cache bibliothèque qui fournit des annotations standard pour permettre une succincte style de codage. En utilisant l'interface de la Carte, il fournit un environnement propre modèle de composition lors de la combinaison avec l'auto-remplissage, expirational, et evictible carte décorateurs. Je suis sûr que quelqu'un pourrait venir avec une belle programmation de l'interface pour une utilisation directe où il est acceptable de perdre le bénéfice de la Carte d'interface.
OriginalL'auteur Ben Manes