.NET中有排序的集合类型吗?

bejyjqdl  于 2023-01-14  发布在  .NET
关注(0)|答案(7)|浏览(158)

我正在寻找一个容器,它能保持所有的项都是有序的。我看过SortedList,但是它需要一个单独的键,并且不允许重复的键。我也可以使用一个未排序的容器,并在每次插入后显式地排序它。
用法:

  • 偶尔插入
  • 按顺序频繁遍历
  • 理想情况下,不使用与实际对象分离的键,而是使用比较函数进行排序。
  • 期望但不要求对等价对象进行稳定的分类。
  • 不需要随机接入。

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

3z6pesqy

3z6pesqy1#

您可能想看一下Wintellect Power Collections。它在CodePlex上可用,包含相当多的集合,非常有用。项目中的OrderedBag集合正是您要寻找的。它本质上使用red-black tree来提供非常高效的排序。

iqxoj9l9

iqxoj9l92#

为了回答EBarr的评论,从.NET 4.0开始就有SortedSet<T>。当然,它是一个集合,这意味着您不能有重复的。

uqxowvwt

uqxowvwt3#

如果你只想使用标准集合,那么List<>类的Sort(IComparer<>)函数经常被忽略,你所需要做的就是为你的对象创建一个合适的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())就可以了。我意识到这可能不像容器在每次添加新对象时自动排序那么简单,但对于许多人(像我!)来说,这可能足以成功地完成这项工作,而不需要任何额外的库。

n3h0vuf2

n3h0vuf24#

我将扩展您自己的列表类,正如您提到的,它只在每次插入后排序。由于您的插入不频繁,因此性能影响将最小,并且对几乎排序的列表排序非常快,扩展泛型列表并重写Add方法以立即排序。如果性能成为问题,您可以在适当的位置插入以保存一些时间。此外,您还可以将插入操作排队,以便为所有要插入的值执行一次遍历插入。

o2g1uqev

o2g1uqev5#

正如我今天早些时候提到的,C5 Generic Collection Library有适合您的容器。

db2dz4w8

db2dz4w86#

如果key也是对象的一个属性,你可以尝试System.Collections.ObjectModel.KeyedCollection<TKey, TItem>,它是一个抽象类,但是如果你的key只是一个属性,那么它真实的容易派生。

lqfhib0f

lqfhib0f7#

下面是我在VB 6中使用的一个老技巧,用于按字母顺序排序:使用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


真的

相关问题