我正在寻找一个可以将所有物品整齐排列的容器。我查看了 SortedList,但这需要一个单独的键,并且不允许重复的键。我也可以只使用未排序的容器,并在每次插入后显式对其进行排序。

用法:

  • 偶尔插入
  • 频繁按顺序遍历
  • 理想情况下,不要使用与实际对象分开的键,而是使用比较函数进行排序。
  • 需要对等效对象进行稳定排序,但不是必需的。
  • 不需要随机访问。

我意识到我可以为自己构建一个平衡的树结构,我只是想知道框架是否已经包含这样的野兽。

有帮助吗?

解决方案

您可能想看看 Wintellect 电源系列. 。它可以在 CodePlex 上找到,并且包含很多非常有用的集合。项目中的 OrderedBag 集合正是您正在寻找的。它本质上使用了一个 红黑树 提供相当有效的排序。

其他提示

只是为了让 伊巴尔的评论 作为答案,有 SortedSet<T> 自 .NET 4.0 以来。当然,它是一个集合,这意味着你不能有重复的。

我将扩展您自己的列表类,正如您所提到的,它只是在每次插入后进行排序。由于插入不频繁,因此对性能的影响很小,并且无论如何,对几乎已排序的列表进行排序都很快。扩展通用列表并重写 Add 方法以立即排序。如果性能成为问题,您可以就地插入以节省一些时间。此外,您可以对插入进行排队,以便对要插入的所有值进行一次遍历插入。

如果您只想坚持使用标准集合,那么 Sort(IComparer<>) 的功能 List<> 阶级是一个经常被忽视的阶级。您所需要做的就是创建一个合适的 Comparer<> 为你的对象。例如:

public class PositionDateComparer : IComparer<VehiclePosition>
{
    public int Compare(VehiclePosition x, VehiclePosition y)
    {
        if (x.DateTime == DateTime.MinValue)
        {
            if (y.DateTime == DateTime.MinValue)
            {
                // If x is null and y is null, they're
                // equal. 
                return 0;
            }

            // If x is null and y is not null, y
            // is greater. 
            return -1;
        }

        // If x is not null...
        //
        if (y.DateTime == DateTime.MinValue)
        // ...and y is null, x is greater.
        {
            return 1;
        }

        // ...and y is not null, compare the dates
        //
        if (x.DateTime == y.DateTime)
        {
            // x and y are equal
            return 0;
        }

        if (x.DateTime > y.DateTime)
        {
            // x is greater
            return 1;
        }

        // y is greater
        return -1;
    }
}

然后只需执行 vehiclePositionsList.Sort(new PositionDateComparer()) 每当您想在访问列表之前对列表进行排序时。我意识到这可能不像每次添加新对象时自动排序的容器那么简单,但对于许多人(比如我!)来说,这可能足以成功完成这项工作,而不需要任何额外的库。

正如我今天早些时候提到的 这里, , 这 C5通用集合库 有适合您的容器。

如果键也是对象的属性,您可以尝试 System.Collections.ObjectModel.KeyedCollection<TKey, TItem>. 。它是一个抽象类,但如果您的密钥只是该项目的一个属性,那么派生起来就非常简单。

这是我在 VB6 中使用的一个老技巧,用于按字母顺序对内容进行排序:使用 System.Windows.Forms ListBox 对象,并将其“Sorted”属性设置为 true。在 C# 中,您可以将任何对象插入到列表框中,它会按对象的 ToString() 值按字母顺序对对象进行排序:

对于类模块:


使用 System.Windows.Forms;

    static void Main(string[] args)
    {
        ListBox sortedList = new ListBox();
        sortedList.Sorted = true;

        sortedList.Items.Add("foo");
        sortedList.Items.Add("bar");
        sortedList.Items.Add(true);
        sortedList.Items.Add(432); 

        foreach (object o in sortedList.Items)
        {
            Console.WriteLine(o);
        }

        Console.ReadKey();
    }

这将显示:

432
酒吧

真的

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top