C# .NET 中的反向排序字典
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/931891/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Reverse Sorted Dictionary in .NET
提问by Gal Goldman
Is there any way I can iterate backwards (in reverse) through a SortedDictionary in c#?
有什么方法可以通过 c# 中的 SortedDictionary 向后(反向)迭代?
Or is there a way to define the SortedDictionary in descending order to begin with?
或者有没有办法以降序定义 SortedDictionary 开始?
采纳答案by Dario
The SortedDictionary itself doesn't support backward iteration, but you have several possibilities to achieve the same effect.
SortedDictionary 本身不支持向后迭代,但您有多种可能来实现相同的效果。
Use
.Reverse
-Method (Linq). (This will have to pre-compute the whole dictionary output but is the simplest solution)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); }
Make the dictionary sort in descending order.
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>());
Use
SortedList<TKey, TValue>
instead. The performance is not as good as the dictionary's (O(n) instead of O(logn)), but you have random-access at the elements like in arrays. When you use the generic IDictionary-Interface, you won't have to change the rest of your code.
使用
.Reverse
-Method (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 时,您不必更改其余代码。
Edit :: Iterating on SortedLists
编辑 :: 迭代 SortedLists
You just access the elements by 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]);
}
回答by Jon Skeet
The easiest way to define the SortedDictionary in the reverse order to start with is to provide it with an IComparer<TKey>
which sorts in the reverse order to normal.
以相反的顺序开始定义 SortedDictionary 的最简单方法是为其提供与IComparer<TKey>
正常相反的排序顺序。
Here's some code from MiscUtilwhich might make that easier for you:
以下是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);
}
}
}
You'd then use:
然后你会使用:
var dict = new SortedDictionary<string, int>
(new ReverseComparer<string>(StringComparer.InvariantCulture));
(or whatever type you were using).
(或您使用的任何类型)。
If you only ever want to iterate in one direction, this will be more efficient than reversing the ordering afterwards.
如果您只想朝一个方向迭代,这将比之后颠倒顺序更有效。
回答by BFree
If you're using .NET 3.5, you can use the OrderByDescending extension method:
如果您使用 .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);
}
回答by jpope
There is also a very simple approach if you are dealing with numeric values as the key which is to simply negate them when you create the dictionary.
如果您将数值作为键处理,则还有一种非常简单的方法,即在创建字典时简单地否定它们。
回答by Zheng Chen
Briefly create a reversed sorted dictionary in one line.
在一行中简要地创建一个反向排序的字典。
var dict = new SortedDictionary<int, int>(Comparer<int>.Create((x, y) => y.CompareTo(x)));
There's a way to create a IComparer<T>
using System.Collections.Generic.Comparer<T>
. Just pass a IComparision<T>
delegate to its Create
method to build a IComparer<T>
.
有一种方法可以创建IComparer<T>
using 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);
}
)
);
You can use a lambda expression/local function/methodto replace the delegate if their significance are (TKey, TKey) => int
.
您可以使用lambda 表达式/本地函数/方法来替换委托,如果它们的重要性是(TKey, TKey) => int
.