代码之家  ›  专栏  ›  技术社区  ›  Gal Goldman

NET中的反向排序词典

  •  34
  • Gal Goldman  · 技术社区  · 15 年前

    有什么方法可以通过c#中的SortedDictionary向后(反向)迭代吗?

    5 回复  |  直到 10 年前
        1
  •  75
  •   Dario    15 年前

    SortedDictionary本身不支持反向迭代,但有几种可能实现相同的效果。

    1. .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);
      }
      
    2. 使字典按降序排序。

      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>());
      
    3. 使用 SortedList<TKey, TValue> 相反性能不如字典中的(O(n)而不是O(logn)),但是您可以对数组中的元素进行随机访问。当您使用通用IDictionary接口时,不必更改其余代码。

    您只需通过索引访问元素!

    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]);
    }
    
        2
  •  19
  •   Jon Skeet    15 年前

    按照与开始相反的顺序定义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));
    

    (或您正在使用的任何类型)。

    如果您只想在一个方向上进行迭代,那么这将比随后反转顺序更有效。

        3
  •  9
  •   jpope    13 年前

        4
  •  9
  •   Zheng Chen    6 年前

    简要创建一个反向排序字典 .

    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);
            }
        )
    );
    

    lambda表达式 局部函数 / 如果学员的重要性不高,则更换学员 (TKey, TKey) => int .

        5
  •  -1
  •   BFree    15 年前

    如果您使用的是.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);
            }