Y a-t-il un moyen de parcourir en arrière (inverse) un SortedDictionary dans C#?Dictionnaire inversé trié dans .NET
Ou existe-t-il un moyen de définir le TriedDictionary dans l'ordre décroissant pour commencer?
Y a-t-il un moyen de parcourir en arrière (inverse) un SortedDictionary dans C#?Dictionnaire inversé trié dans .NET
Ou existe-t-il un moyen de définir le TriedDictionary dans l'ordre décroissant pour commencer?
Le dictionnaire SortedDictionary ne prend pas en charge l'itération arrière, mais vous avez plusieurs possibilités pour obtenir le même effet.
utilisation .Reverse
-Méthode (Linq). (Cela devra pré-calculer l'ensemble de sortie de dictionnaire, mais est la solution la plus simple)
var Rand = new Random();
var Dict = new SortedDictionary<int, string>();
for (int i = 1; i <= 10; ++i) {
var newItem = Rand.Next(1, 100);
Dict.Add(newItem, (newItem * newItem).ToString());
}
foreach (var x in Dict.Reverse()) {
Console.WriteLine("{0} -> {1}", x.Key, x.Value);
}
Faire le tri de dictionnaire dans l'ordre décroissant.
class DescendingComparer<T> : IComparer<T> where T : IComparable<T> {
public int Compare(T x, T y) {
return y.CompareTo(x);
}
}
// ...
var Dict = new SortedDictionary<int, string>(new DescendingComparer<int>());
Utilisez SortedList<TKey, TValue>
à la place. La performance n'est pas aussi bonne que celle du dictionnaire (O (n) au lieu de O (logn)), mais vous avez un accès aléatoire aux éléments comme dans les tableaux. Lorsque vous utilisez l'IDictionary-Interface générique, vous n'aurez pas à modifier le reste de votre code.
Modifier :: Itère sur SortedLists
Vous accédez simplement les éléments par index!
var Rand = new Random();
var Dict = new SortedList<int, string>();
for (int i = 1; i <= 10; ++i) {
var newItem = Rand.Next(1, 100);
Dict.Add(newItem, (newItem * newItem).ToString());
}
// Reverse for loop (forr + tab)
for (int i = Dict.Count - 1; i >= 0; --i) {
Console.WriteLine("{0} -> {1}", Dict.Keys[i], Dict.Values[i]);
}
Merci, ce fut vraiment utile! –
La meilleure façon de définir la SortedDictionary dans l'ordre inverse pour commencer est de lui fournir une IComparer<TKey>
qui trie dans l'ordre inverse à la normale.
est Voici une partie de MiscUtil qui pourrait rendre plus facile pour vous que:
using System.Collections.Generic;
namespace MiscUtil.Collections
{
/// <summary>
/// Implementation of IComparer{T} based on another one;
/// this simply reverses the original comparison.
/// </summary>
/// <typeparam name="T"></typeparam>
public sealed class ReverseComparer<T> : IComparer<T>
{
readonly IComparer<T> originalComparer;
/// <summary>
/// Returns the original comparer; this can be useful
/// to avoid multiple reversals.
/// </summary>
public IComparer<T> OriginalComparer
{
get { return originalComparer; }
}
/// <summary>
/// Creates a new reversing comparer.
/// </summary>
/// <param name="original">The original comparer to
/// use for comparisons.</param>
public ReverseComparer(IComparer<T> original)
{
if (original == null)
{
throw new ArgumentNullException("original");
}
this.originalComparer = original;
}
/// <summary>
/// Returns the result of comparing the specified
/// values using the original
/// comparer, but reversing the order of comparison.
/// </summary>
public int Compare(T x, T y)
{
return originalComparer.Compare(y, x);
}
}
}
Vous seriez alors utiliser:
var dict = new SortedDictionary<string, int>
(new ReverseComparer<string>(StringComparer.InvariantCulture));
(ou quel que soit le type que vous utilisiez).
Si vous ne voulez que parcourir dans une direction, ce sera plus efficace que d'inverser la commande par la suite.
Il serait très utile de fournir une méthode de moulage intégrée au framework de Comparaison
J'ai aussi une classe dans MiscUtil :) –
Nice ;-) Devrait faire partie du cadre de toute façon. Il y a même une telle classe en interne mais elle est privée ;-) – Dario
Si vous utilisez .NET 3.5, vous pouvez utiliser la méthode d'extension OrderByDescending:
var dictionary = new SortedDictionary<int, string>();
dictionary.Add(1, "One");
dictionary.Add(3, "Three");
dictionary.Add(2, "Two");
dictionary.Add(4, "Four");
var q = dictionary.OrderByDescending(kvp => kvp.Key);
foreach (var item in q)
{
Console.WriteLine(item.Key + " , " + item.Value);
}
Il y a aussi une approche très simple si vous avez affaire à des valeurs numériques comme la clé qui est de nier tout simplement eux quand vous créez le dictionnaire.
Créez rapidement un dictionnaire trié inversé en une ligne.
var dict = new SortedDictionary<int, int>(Comparer<int>.Create((x, y) => y.CompareTo(x)));
Il y a un moyen de créer un IComparer<T>
en utilisant System.Collections.Generic.Comparer<T>
. Passez simplement un délégué IComparision<T>
à sa méthode Create
pour créer un IComparer<T>
.
var dict = new SortedDictionary<int, TValue>(
Comparer<int>.Create(
delegate(int x, int y)
{
return y.CompareTo(x);
}
)
);
Vous pouvez utiliser une expression lambda/fonction locale/méthode pour remplacer le délégué si leur signification sont (TKey, TKey) => int
.
Vous ne voulez pas dire Dictionnaire ... –
Oui, je pense que ;-) – Dario
Typo ... Merci pour tous les compilateurs humains :-) –