【问题标题】:Is there a non-unique-key sorted list generic collection in C#?C# 中是否有非唯一键排序列表泛型集合?
【发布时间】:2009-11-17 09:54:27
【问题描述】:

我对 System.Collections.Generic.SortedList 有点惊讶

  1. 它要求我使用<key, value> 而不是<value>(比较器)
  2. 它只允许按值输入

这些在我想使用它的方式上看起来很古怪(尽管我确信它们适合其他情况)。还有没有这两个特点的系列吗?

【问题讨论】:

  • 你想怎么使用它?您对特定系列必须满足哪些要求?
  • @Russ - 根据我的需要,它很像 List<KeyValuePair<K, V>>,只是它支持按键二分搜索。

标签: c# collections sortedlist


【解决方案1】:

SortedList<,> 实际上是一个按键排序的地图,而不是一个列表。不好的命名,也许。但是有一些方法可以模拟你想要的,这取决于你的确切要求。例如,您可以封装 SortedList<T, int> 并添加/删除类似的内容:

// add
int count;
if(list.TryGetValue(value, out count)) list[value] = count+1;
else list[value] = 1;

最终你也可以使用一个简单的列表 (List<>) - 这取决于你在做什么。

在某种程度上,我预计数据绑定等会导致难以实现立即排序的常规列表 - 您需要实现 lot 的接口才能使其正常工作,因为它通常期望添加到最后的项目。

【讨论】:

    【解决方案2】:

    我知道这是一个老问题,但我刚刚遇到了另一个问题 (C# Sortable collection which allows duplicate keys),它提供了一个解决方案:将您自己的 IComparer 与 SortedSet 一起使用! 即

    /// <summary>
    /// Comparer for comparing two keys, handling equality as being greater
    /// Use this Comparer e.g. with SortedSets, SortedLists or SortedDictionaries, that don't allow duplicate keys
    /// </summary>
    /// <typeparam name="TKey"></typeparam>
    public class DuplicateKeyComparer<TKey> : IComparer<TKey> where TKey : IComparable
    {
        #region IComparer<TKey> Members
    
        public int Compare(TKey x, TKey y)
        {
            int result = x.CompareTo(y);
    
            return result == 0 ? 1 : result; // Handle equality as being greater
        }
    
        #endregion
    }
    

    用法:

    SortedSet<T> mySortedValues = new SortedSet<T>(new DuplicateKeyComparer<T>());
    

    编辑:再想一想,这对于SortedSet&lt;T&gt; 以外的任何东西可能都是个坏主意,因为您可能无法使用foreach 循环以外的任何东西查找与重复键关联的不同值;而SortedSet&lt;T&gt; 最好用SortedList&lt;TKey,TValue&gt; 表示,其中TKey 是有趣的值,TValue 是该对象重复数的计数(例如int)。

    【讨论】:

      【解决方案3】:

      我不确定这是否符合您的要求。但是您可以对普通列表进行排序。 MSDN 讲了,不过显然这需要调用 sort。

      【讨论】:

        【解决方案4】:

        我尝试过寻找同样的东西:基本上是一个在您向其中添加项目时保持有序的列表。到目前为止,我发现的最接近的是来自 Goletas.Collections 的 SortedSet,它使用 AVL 树实现:

        http://www.goletas.com/solutions/collections/

        但是这个类仍然要求列表中的每个元素都是唯一的(因此是“Set”)。

        也许可以修改这个类以支持非唯一项。

        【讨论】:

          【解决方案5】:

          如果它不是性能关键,您可以使用任一

          1) Linq OrderBy()

          2) 列表方法Sort()

          看这个例子

                  var list = new List<int>();
                  list.Add( 2);
                  list.Add( 1);
                  list.Add( 3);
          
                  Console.WriteLine("Using Linq OrderBy");
                  foreach (int i in list.OrderBy(i=>i))
                      Console.WriteLine(i);
          
                  Console.WriteLine("Using List.Sort()");
                  list.Sort();
                  foreach (int i in list)
                      Console.WriteLine(i);
          

          【讨论】:

          • 问题是关于排序的数据结构(即在插入时将元素置于其排序位置的东西),而不是排序列表的方法。
          猜你喜欢
          • 2010-09-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-04-04
          • 2010-10-14
          • 1970-01-01
          • 2014-08-25
          • 2021-12-04
          相关资源
          最近更新 更多