¿Hay alguna forma de que pueda repetir hacia atrás (en reversa) a través de SortedDictionary en C#?Diccionario revertido ordenado en .NET
¿O hay una manera de definir SortedDictionary en orden descendente para empezar?
¿Hay alguna forma de que pueda repetir hacia atrás (en reversa) a través de SortedDictionary en C#?Diccionario revertido ordenado en .NET
¿O hay una manera de definir SortedDictionary en orden descendente para empezar?
SortedDictionary en sí no admite la iteración hacia atrás, pero tiene varias posibilidades para lograr el mismo efecto.
Uso .Reverse
-Método (LINQ). (Esto tiene que pre-calcular toda la salida de diccionario, pero es la solución más 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);
}
hacer algún tipo de diccionario en orden descendente.
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>());
Uso SortedList<TKey, TValue>
lugar. El rendimiento no es tan bueno como el del diccionario (O (n) en lugar de O (logn)), pero tiene acceso aleatorio en los elementos como en las matrices. Cuando use el IDictionary-Interface genérico, no tendrá que cambiar el resto de su código.
Editar :: iterando SortedLists
Usted acaba de acceder a los elementos de índice!
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]);
}
¡Gracias, eso fue realmente útil! –
La forma más fácil de definir el SortedDictionary en el orden inverso para empezar es para dotarla de un IComparer<TKey>
que ordena en orden inverso a la normalidad.
Aquí hay un código de MiscUtil lo que podría hacer que más fácil para usted:
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);
}
}
}
te había hacemos lo siguiente:
var dict = new SortedDictionary<string, int>
(new ReverseComparer<string>(StringComparer.InvariantCulture));
(o lo que sea el tipo que estaba usando).
Si solo desea iterar en una dirección, esto será más eficiente que invertir el orden posteriormente.
Sería bastante útil proporcionar un método de conversión integrado en el marco de la Comparación
También tengo una clase en MiscUtil :) –
Bueno ;-) Debería ser parte del framework de todos modos. Incluso hay una clase interna, pero se mantiene privada ;-) – Dario
Si está utilizando .NET 3.5, puede utilizar el método de extensión 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);
}
También hay un enfoque muy simple si se trata de valores numéricos como la llave que es simplemente negar ellos cuando creas el diccionario.
Cree brevemente un diccionario ordenado inverso en una línea.
var dict = new SortedDictionary<int, int>(Comparer<int>.Create((x, y) => y.CompareTo(x)));
Hay una manera de crear una IComparer<T>
usando System.Collections.Generic.Comparer<T>
. Simplemente pase un delegado IComparision<T>
al método Create
para crear un IComparer<T>
.
var dict = new SortedDictionary<int, TValue>(
Comparer<int>.Create(
delegate(int x, int y)
{
return y.CompareTo(x);
}
)
);
Se puede utilizar una expresión lambda /función local/método para sustituir al delegado cuando su naturaleza son (TKey, TKey) => int
.
¿Quieres decir Dictionary ... –
Sí, creo que sí ;-) – Dario
Typo ... Gracias por todos los compiladores humanos :-) –