C# 如何就地对 Collection<T> 进行排序?

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

How to sort a Collection<T> in-place?

c#.netsorting

提问by Ian Boyd

I have a generic collection:

我有一个通用集合:

public Items : Collection<Object>
{
   protected override void InsertItem(int index, Object item)
   {
      base.InsertItem(index, item);
      ...
   }

   protected override void RemoveItem(int index)
   {
      base.RemoveItem(index);
      ...
   }

   protected override void SetItem(int index, Object item)
   {
      base.SetItem(index, item);
      ...
   }

   protected override void ClearItems()
   {
      base.ClearItems();
      ...
   }

Now I need a way to sort this collection in-place.

现在我需要一种方法来就地排序这个集合。

Bonus Chatter

奖金喋喋不休

I tried converting my class to use List<T>rather than Collection<T>(since Collection<T>doesn't support the concept of an order). That then allowed calling the Sortmethod:

我尝试将我的班级转换为 useList<T>而不是Collection<T>(因为Collection<T>不支持订单的概念)。然后允许调用该Sort方法:

this.Items.Sort(SortCompareCallback);

protected virtual int SortCompareCallback(Object x, Object y)
{
   return OnCompareItems(new SortCompareEventArgs(x, y, this.sortColumnIndex, direction));
}

But then I lose the virtual methods when the list is modified.

但是当列表被修改时,我丢失了虚拟方法。

I thought about using Linq, but the problem with that is:

我想过使用 Linq,但问题是:

  • I don't know how to call a callback from a Linq expression
  • Linq doesn't sort a collection, it can only return a new one
  • 我不知道如何从 Linq 表达式调用回调
  • Linq 不对集合进行排序,它只能返回一个新集合

How can I sort a generic Collection<T>?

如何对泛型进行排序Collection<T>

采纳答案by phoog

If you don't need to have the virtual overrides called during the sorting, you should be able to do something like this:

如果您不需要在排序期间调用虚拟覆盖,您应该能够执行以下操作:

class SortableCollection<T> : Collection<T>
{
    private readonly List<T> _list;

    public SortableCollection() : this(new List<T>()) {}
    public SortableCollection(List<T> list) : base(list)
    {
        _list = list;
    }
    public void Sort() { _list.Sort(); }
}

Or this:

或这个:

class SortableCollection<T> : Collection<T>
{
    public SortableCollection() : this(new List<T>()) {}
    public SortableCollection(List<T> list) : base(list) {}
    public void Sort() { ((List<T>)Items).Sort(); }
}

回答by Eric J.

You can use SortedList<T>(which also implements ICollection<T>, so you can treat it like a collection if you want to).

您可以使用SortedList<T>(它也实现了ICollection<T>,因此您可以根据需要将其视为集合)。

回答by Chris Shain

If you want a sortable list with content change notification, you should look at BindingList

如果您想要一个带有内容更改通知的可排序列表,您应该查看BindingList

回答by zmbq

Collection<T>has an indexer. If you really want to sort the items in place, you can implement whatever sorting algorithm you prefer using the indexer. Here's an example that, with the proper Collection, can take O(N^3)...

Collection<T>有一个索引器。如果您真的想就地对项目进行排序,则可以使用索引器实现您喜欢的任何排序算法。这是一个示例,使用适当的 Collection,可以采用 O(N^3)...

void SortInPlace(Collection<T> col)
{
    for(int i=0; i<col.Count - 1; i++)
        for(int j=i+1; j<col.Count; j++)
            if(col[i] < col[j]) // This won't compile, but you get the jist
                Swap col[i] and col[j]
}

You can implement one of the O(NlogN) algorithms to get an O(N^2logN) sort performance if your collection only offers O(N) item access.

如果您的集合仅提供 O(N) 项访问,您可以实现 O(NlogN) 算法之一以获得 O(N^2logN) 排序性能。

回答by Aditya

Yes you can sort a collection try this:

是的,您可以对集合进行排序,试试这个:

public ICollection<T> getSortedData(ICollection<T> collection, string property, string direction)
{
    switch (direction.Trim())
    {
        case "asc":
            collection = ((from n in collection
                           orderby
                           n.GetType().GetProperty(property).GetValue(n, null)
                           select n).ToList<T>()) as ICollection<T>;
        break;
        case "desc":
            collection = ((from n in collection
                           orderby
                           n.GetType().GetProperty(property).GetValue(n, null)
                           descending
                           select n).ToList<T>()) as ICollection<T>;
        break;
    }
    return collection;
}

回答by Dmitry Martynov

Use ArrayList.Adapter(yourCollection)and sort it as an array.

ArrayList.Adapter(yourCollection)其用作数组并将其排序。