.NET 中的反向排序字典
-
06-09-2019 - |
题
有什么方法可以向后(反向)迭代 C# 中的 SortedDictionary 吗?
或者有没有办法首先按降序定义 SortedDictionary ?
解决方案
SortedDictionary 本身不支持向后迭代,但您有多种可能性来实现相同的效果。
使用
.Reverse
-方法(Linq)。(这必须预先计算整个字典输出,但这是最简单的解决方案)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); }
使字典按降序排序。
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>());
使用
SortedList<TKey, TValue>
反而。性能不如字典(O(n) 而不是 O(logn)),但您可以像数组一样随机访问元素。当您使用通用 IDictionary-Interface 时,您无需更改其余代码。
编辑 ::迭代排序列表
您只需通过索引访问元素即可!
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]);
}
其他提示
以相反的顺序开始与以限定SortedDictionary最简单的方法是提供其与排序以相反的顺序正常的IComparer<TKey>
。
下面是从 MiscUtil 一些代码,这可能使它可以简化工作:
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);
}
}
}
您最好再使用:
var dict = new SortedDictionary<string, int>
(new ReverseComparer<string>(StringComparer.InvariantCulture));
(或任何你正在使用的类型)。
如果您只想在一个方向进行迭代,这将是比事后扭转排序更有效。
还有,如果你正在处理的数值作为是简单地否定他们当你创建字典的关键一个非常简单的方法。
简言之创建反转排序字典的在一个行强>
var dict = new SortedDictionary<int, int>(Comparer<int>.Create((x, y) => y.CompareTo(x)));
有创建使用IComparer<T>
一个System.Collections.Generic.Comparer<T>
的方式。只是传递IComparision<T>
委托其Create
方法建立一个IComparer<T>
。
var dict = new SortedDictionary<int, TValue>(
Comparer<int>.Create(
delegate(int x, int y)
{
return y.CompareTo(x);
}
)
);
可以使用的λ表达式强> / 本地功能强> / 方式如果它们的意义是(TKey, TKey) => int
更换委托。
如果您使用的.NET 3.5,则可以使用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);
}