Gibt es eine Möglichkeit, rückwärts (in umgekehrter Reihenfolge) durch ein SortedDictionary in C# zu iterieren?Reverse Sorted Dictionary in .NET
Oder gibt es eine Möglichkeit, das SortedDictionary in absteigender Reihenfolge zu definieren?
Gibt es eine Möglichkeit, rückwärts (in umgekehrter Reihenfolge) durch ein SortedDictionary in C# zu iterieren?Reverse Sorted Dictionary in .NET
Oder gibt es eine Möglichkeit, das SortedDictionary in absteigender Reihenfolge zu definieren?
Das SortedDictionary selbst unterstützt keine Rückwärtsiteration, aber Sie haben mehrere Möglichkeiten, denselben Effekt zu erzielen.
Verwenden Sie .Reverse
-Methode (Linq). (Dies muss die ganze Wörterbuch Ausgabe vorab berechnen, aber die einfachste Lösung)
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);
}
das Wörterbuch art Marke in absteigender Reihenfolge.
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>());
Verwenden SortedList<TKey, TValue>
statt. Die Leistung ist nicht so gut wie die des Wörterbuchs (O (n) statt O (logn)), aber Sie haben zufälligen Zugriff auf die Elemente wie in Arrays. Wenn Sie das generische IDictionary-Interface verwenden, müssen Sie den Rest Ihres Codes nicht ändern.
bearbeiten :: Iterieren auf SortedLists
Sie greifen nur die Elemente von 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]);
}
Danke, das war wirklich hilfreich! –
Der einfachste Weg, um die SortedDictionary in umgekehrter Reihenfolge, mit zu beginnen zu definieren, ist es mit einem IComparer<TKey>
, die normal in umgekehrter Reihenfolge sortiert zur Verfügung zu stellen.
Hier ist ein Code aus MiscUtil, die das leichter machen könnten:
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);
}
}
}
Sie würden dann verwenden:
var dict = new SortedDictionary<string, int>
(new ReverseComparer<string>(StringComparer.InvariantCulture));
(oder wie auch immer geartete Sie verwendet).
Wenn Sie immer nur in eine Richtung iterieren möchten, ist dies effizienter als die Reihenfolge danach umzukehren.
Es wäre sehr nützlich, eine Framework-integrierte Casting-Methode aus Comparison
Ich habe auch eine Klasse in MiscUtil dafür :) –
Schön ;-) Sollte sowieso ein Teil des Frameworks sein. Es gibt sogar eine solche Klasse intern aber es wird privat gehalten ;-) – Dario
Wenn Sie .NET 3.5, können Sie sich die OrderByDescending Extension-Methode verwenden:
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);
}
Es gibt auch einen sehr einfachen Ansatz, wenn Sie mit numerischen Werten als Schlüssel handeln, die einfach zu negieren sie beim Erstellen des Wörterbuchs.
Erstellen Sie kurz ein umgekehrt sortiertes Wörterbuch in einer Zeile.
var dict = new SortedDictionary<int, int>(Comparer<int>.Create((x, y) => y.CompareTo(x)));
Es gibt einen Weg, um eine IComparer<T>
mit System.Collections.Generic.Comparer<T>
zu erstellen. Übergeben Sie einfach einen IComparision<T>
Delegaten an seine Create
Methode, um eine IComparer<T>
zu bauen.
var dict = new SortedDictionary<int, TValue>(
Comparer<int>.Create(
delegate(int x, int y)
{
return y.CompareTo(x);
}
)
);
Sie können einen Lambda-Ausdruck/lokale Funktion/Methode die Delegierten zu ersetzen, wenn ihre Bedeutung (TKey, TKey) => int
ist.
Meinst du nicht Wörterbuch ... –
Ja, ich denke schon ;-) – Dario
Typo ... Danke für all die menschlichen Compiler :-) –