2010-05-06 3 views
8

J'ai un SortedDictionary tel que défini comme ceci:Dictionnaire inversé trié?

SortedDictionary<TPriority, Queue<TValue>> dict; 

Mais je veux maintenir le dict dans l'ordre inverse. Je suppose que j'ai besoin de définir le Comparer, mais ce que j'utilise un comparateur générique TPriority? Notez que TPriority implémente IComparable.

+0

double possible de [inverse Classé dans le dictionnaire .NET] (http://stackoverflow.com/questions/931891/reverse-sorted-dictionary-in -net) – nawfal

Répondre

16

Vous pouvez créer un comparateur inverse assez facilement:

public sealed class ReverseComparer<T> : IComparer<T> { 
    private readonly IComparer<T> inner; 
    public ReverseComparer() : this(null) { } 
    public ReverseComparer(IComparer<T> inner) { 
     this.inner = inner ?? Comparer<T>.Default; 
    } 
    int IComparer<T>.Compare(T x, T y) { return inner.Compare(y, x); } 
} 

maintenant passer que dans le constructeur pour le dictionnaire:

var dict = new SortedDictionary<TPriority, Queue<TValue>>(
       new ReverseComparer<TPriority>()); 
+0

Battez-moi au coup de poing. :-p – LBushkin

+0

Pourquoi passer 'null' et ensuite vérifier, quand vous auriez pu passer dans 'Comparer .Default' en premier lieu? – mpen

+0

Utilisation savante des opérateurs 'sealed',' readonly' et de coalescence nulle. –

1

Si vous pouvez utiliser LINQ, vous pouvez simplement faire:

dict.Keys.Reverse(); 

Cela donne les clés de la collection dans l'ordre inverse.

EDIT: La classe SortedDictionary est affectée d'un IComparer<T> lors de sa construction et ne peut pas être modifiée après coup. Cependant, vous pouvez créer une nouvelle SortedDictionary<T> de l'original:

class ReverseComparer<T> : IComparer<T> { 
    private readonly m_InnerComparer = new Comparer<T>.Default; 

    public ReverseComparer(IComparer<T> inner) { 
     m_InnerComparer = inner; } 

    public int Compare(T first, T second) { 
     return -m_InnerComparer.Compare(first, second); } 
} 

var reverseDict = new SortedDictionary<TPriority, Queue<TValue>>(dict, 
          new ReverseComparer(Comparer<TPriority>.Default)); 
+0

Eh bien, je ne voulais pas dire que je voulais les touches dans l'ordre inverse, je voulais dire que je veux maintenir la dict dans l'ordre inverse de sorte que lorsque je l'itérer, il sera toujours dans l'ordre décroissant ... – mpen

+0

@Mark: Peut-être que vous n'auriez pas dû dire que vous vouliez les touches dans l'ordre inverse. Vous devriez éditer votre question pour vous assurer qu'elle est claire pour le bénéfice de ceux qui chercheront dans le futur. –

+0

@Tom: Je n'ai pas dit que je "voulais les touches dans l'ordre inverse". J'ai dit que je voulais trier les clés dans l'ordre inverse, triant ainsi la dict. J'ai dit "clés" pour distinguer du tri des files d'attente/TValues, mais je comprends d'où vient la confusion. Modifié. – mpen

1

J'ai fini par ajouter ceci à ma classe, car c'est le plus court et le plus simple:

private class ReverseComparer : IComparer<TPriority> 
{ 
    public int Compare(TPriority x, TPriority y) { return y.CompareTo(x); } 
} 

Et puis initialiser le dict comme ceci:

dict = new SortedDictionary<TPriority, Queue<TValue>>(new ReverseComparer());