如何使用.NET排序大量列表的一部分?

时间:2010-03-08 06:27:56

标签: .net vb.net generics sorting

在.NET中,泛型列表具有接受IComparerComparison的排序功能。我想只列出一份清单的一部分。希望我可以指定起始索引,要排序的元素数和lambda函数。看起来如果要对整个列表进行排序,只能使用lambda函数来执行此操作。这是对的还是我错过了什么?

附加要求:

  • 就地排序(以节省内存/时间)
  • 最终列表与原始列表的长度相同

4 个答案:

答案 0 :(得分:1)

List<int> mylist = new List<int>() {8,4,6,2,1,5,3,1,7};
List<int> myRange = mylist.GetRange(2,4);

mylist.RemoveRange(2, 4);
mylist.InsertRange(2,  myRange.OrderBy(i => i));

mylist.Dump();

编辑:将Dump视为在列表中运行foreach&amp;将其打印到控制台。
这正在改变原始列表的内容。

EDIT2:看看这段代码是否有帮助

    List<int> mylist = new List<int>() ;
    for(int i=9999999; i > 0; i--)
    {
        mylist.Add(i);
    }

    Console.WriteLine("start " + DateTime.Now.Ticks);
    var extract = mylist.Skip(10).Take(1000000).OrderBy(i => i);

    int k = 10; // start from (because we skipped from 10 onwards above)
    foreach(int item in extract)
    {
        mylist[k++] = item;
    }


    Console.WriteLine("done" + DateTime.Now.Ticks);
    foreach(int item in mylist)
        Console.WriteLine(item);

答案 1 :(得分:1)

您可以提取子列表,然后将其复制回来,而不是RemoveRangeInsertRange。是的,我知道,这不是原地,但是没有重写Sort你将找不到这样的解决方案。

Dim myList As New List<int>() { 8, 4, 6, 2, 1, 5, 3, 1, 7 }
Dim myRange = myList.GetRange(2,4)

myRange.Sort(yourComparer)
Dim i = 2;
For Each item in myRange
    mylist(i) = item
    i += 1
Next

答案 2 :(得分:0)

如果你能找到一种方法来使用一些过滤工具,你可以使用list或linq方法。以下是使用FindAll的示例。

genericList = genericList.FindAll(x => x.Field).OrderBy(y => y.Field).ToList();

答案 3 :(得分:0)

您是否要求列表在此之后仍需要包含所有项目,或者您是否只处理订购的子集?如果是后者那么你可以使用常规的Linq来做到这一点 - 这样的事情可能适合你。

IEnumerable<T> enumerable = GetTheListToWorkWith();
IEnumerable<T> sortedStuff = enumerable.Skip(startIndex).Take(endIndex).OrderBy(t => t.ValueToCompare);

此方法不会更改原始列表 - 它只会返回一个新的IEnumerable,它只包含List的已排序部分。

作为备用(如果所有数据都需要保留在列表中,您可以删除需要排序的子集,对其进行排序,然后将其重新附加到原始列表