2009-02-16 12 views
18

Possible en double:
C# Sortable collection which allows duplicate keysExiste-t-il une alternative à Dictionary/SortedList qui autorise les doublons?

En fait, je voudrais faire un travail Dictionnaire des clés en double sans entrer dans les implémentations de comparateur personnalisé. Il y a une idée de:

Dictionary<key, List<value>> 

mais il y a encore un peu de temps. Je souhaite Dictionnaire avait "AllowDuplicates".

+0

N'a pas trouvé cela dans mes recherches. Voté pour fermer, merci. –

+0

Également en rapport: http: // stackoverflow.com/questions/5716423/c-sharp-sortable-collection-which-allow-duplicate-keys –

Répondre

13

Si vous utilisez .NET 3.5 puis Lookup est probablement ce que vous cherchez.

+4

Il est dommage qu'une telle classe potentiellement utile a quelques limitations. Comme aucun constructeur public ou la capacité d'ajouter/supprimer des éléments. – Ray

+2

@Ray, D'accord complètement. Bien que j'imagine que c'est pour ça qu'on l'appelle Lookup plutôt que quelque chose comme MultiDictionary, pour suggérer qu'il s'agit d'une recherche immuable plutôt que d'une collection à manipuler. La suggestion d'OP d'une clé Dictionary <, Liste > serait beaucoup plus flexible. – LukeH

+0

@Ray: Le meilleur constructeur est, et je cite MSDN: "Vous pouvez créer une instance d'un Lookup en appelant ToLookup sur un objet qui implémente IEnumerable " –

3

Pas dans le Fx < 3.5 .. Vous pouvez en implémenter un, évidemment, avec un dictionnaire d'objets IList. Mais alors vous avez la question/la responsabilité de l'encapsulation.

Si vous utilisez .NET 3.5, utilisez la classe Lookup.

+0

C'est seulement un remplacement de 'Dictionary', mais pas de' SortedList'. –

0

Par définition, un dictionnaire contient des clés uniques. Votre exemple ci-dessus est en fait une sorte de tableau à clés en deux dimensions, une structure que j'ai utilisée plusieurs fois. Pourquoi voudriez-vous avoir des clés en double? Si vous le faisiez, comment le Dictionnaire s'adresserait-il uniquement à ses membres?

+5

Considérons un dictionnaire du monde réel énumérant différentes significations pour le même mot. Entrées multiples avec une clé commune. Rien de contradictoire à ce sujet. Les membres peuvent être adressés par une recherche retournant une collection ou Enumerable. C++ a eu un multimap depuis des lustres. Ce n'est pas un problème impossible. :) – jalf

1

je suis tombé avec la même question .. Je avais besoin d'un SortedList qui peut permettre des clés en double ..

var sortList = new SortedList<string, IDictionary<string, object>>(); 

mais ce travail na pas .. donc je l'ai utilisé

var list = new List<KeyValuePair<string, IDictionary<string, object>>>(); 

ajouter de nouvelles données à comme ..

list.Add(new KeyValuePair<string, IDictionary<string, object>>>(value, Dictionary)); 

avec LINQ i il triai sans problème ..

Essayez List<KeyValuePair<TKey, List<TValue>>>();

+4

Ne pas oublier que cela a La recherche O (N) coûte par clé contrairement à une hashtable (ou un dictionnaire), qui est O (1) principalement. –

4

Vous pouvez toujours utiliser SortedList et essayer de faire une clé unique en combinant votre valeur et un Guid dans une classe. Dans ce cas, vous devez mettre en œuvre la IComparer<NewKey> pour votre nouvelle clé, quelque chose comme:

class MyKey 
{ 
    public Guid Guid { get; set; } 
    public float Value { get; set; } 
} 

class MyComparer : IComparer<MyKey> 
{ 

    public int Compare(MyKey x, MyKey y) 
    { 
     if (x == null || y == null) 
      throw new InvalidOperationException("both of parameters must be not null"); 
     if (x.Value < y.Value) return -1; 
     if (x.Value > y.Value) return 1; 
     return 0; 
    } 
} 

puis

var mySortedList = new SortedList<MyKey, MyValue>(new MyComparer()); 
2

qui ne fonctionne pas. Dès que vous retournez 0 du comparateur, il lancera l'exception "duplicate".

Vous n'avez pas besoin d'encapsulation de classe ou quoi que ce soit, faites simplement un comparateur qui ne retourne pas le résultat 0 (égal). Voici un exemple pour int type de clé

class MyComparer : IComparer<int> 
{ 

    public int Compare(int x, int y) 
    { 
    if (x < y) 
     return -1; 
    else return 1; 
    } 
} 
+3

Gardez à l'esprit que cette astuce va casser l'indexeur. Si vous essayez d'obtenir une valeur en utilisant l'indexeur, vous obtiendrez une exception car la clé n'a pas pu être trouvée. –