C# .NET 中是否有排序的集合类型?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/196512/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 17:36:16  来源:igfitidea点击:

Is there a sorted collection type in .NET?

c#.netsortingcontainers

提问by Eclipse

I'm looking for a container that keeps all its items in order. I looked at SortedList, but that requires a separate key, and does not allow duplicate keys. I could also just use an unsorted container and explicitly sort it after each insert.

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

Usage:

用法:

  • Occasional insert
  • Frequent traversal in order
  • Ideally not working with keys separate from the actual object, using a compare function to sort.
  • Stable sorting for equivalent objects is desired, but not required.
  • Random access is not required.
  • 偶尔插入
  • 频繁的有序遍历
  • 理想情况下不使用与实际对象分开的键,使用比较函数进行排序。
  • 对等价对象的稳定排序是需要的,但不是必需的。
  • 不需要随机访问。

I realize I can just build myself a balanced tree structure, I was just wondering if the framework already contains such a beast.

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

采纳答案by JeremiahClark

You might want to take a look at the Wintellect Power Collections. It is available on CodePlex and contains quite a few collections that are very helpful. The OrderedBag collection in the project is exactly what you are looking for. It essentially uses a red-black treeto provide a pretty efficient sort.

您可能想看看Wintellect Power Collections。它在 CodePlex 上可用,并且包含很多非常有用的集合。项目中的 OrderedBag 集合正是您要寻找的。它本质上使用红黑树来提供非常有效的排序。

回答by Joel Coehoorn

If the key is also an attribute of the object, you might try the System.Collections.ObjectModel.KeyedCollection<TKey, TItem>. It's an abstract class, but if your key is just a property of the item then it's real simple to derive from.

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

回答by Joe Basirico

I would extend your own list class that, as you mentioned, simply sorts after every insert. Since your inserts are infrequent the performance hit would be minimal, and sorting a nearly sorted list is quick, in any case. Extend the Generic List and override the Add method to sort immediately. If performance becomes an issue you can insert in place to save some time. Furthermore you can queue up your inserts to do a single traversal insertion for all the values you want to insert.

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

回答by Perry Pederson

Here's an old trick I used way back in VB6 to sort things alphabetically: Use a System.Windows.Forms ListBox object, and set its "Sorted" property to true. In C#, you can insert any object into the listbox, and it will sort the object alphabetically by its ToString() value:

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

for a class module:

对于类模块:



using System.Windows.Forms;

使用 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();
    }


This will display:

这将显示:

432
bar
foo
True

432

FOO

回答by tobsen

As I mentioned earlier today here, the C5 Generic Collection Libraryhas the proper container for you.

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

回答by Jason

If you just want to stick with the standard collections then the Sort(IComparer<>)function of the List<>class is one that often gets ignored. All you need to do is create a suitable Comparer<>for your objects. For example:

如果您只想坚持使用标准集合,那么该类的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;
    }
}

Then just perform a vehiclePositionsList.Sort(new PositionDateComparer())whenever you want to sort the list before accessing it. I realise that this might not be as simple as a container which automatically sorts every time you add a new object, but for many (like me!) this might be enough to do the job successfully without requiring any additional libraries.

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

回答by nawfal

Just to make EBarr's commentas answer, there is SortedSet<T>since .NET 4.0. Of course it is a set, which means you cannot have duplicates.

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