开发者

How can I sort just part of a huge list using .NET?

开发者 https://www.devze.com 2022-12-22 17:51 出处:网络
In .NET, the Generics Lists have a sort function that accepts IComparer or Comparison.I\'d like to sort just part of a list.Hopefully I can specify the start index, count of elements to sort, and a la

In .NET, the Generics Lists have a sort function that accepts IComparer or Comparison. I'd like to sort just part of a list. Hopefully I can specify the start index, count of elements to sort, and a lambda function. It looks like you can only use lambda functions to do this if you're sorting the entire list. Is that right or did I miss something?

Additional Requirements:

  • Sort in place (to save memory/time)
  • Final list has the same length as the original l开发者_开发问答ist


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();

EDIT: Think of Dump as running a foreach on the list & printing it to the console.
And this is changing the content of the original list.

EDIT2: See if this code helps at all

    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);


Instead of RemoveRange and InsertRange you could extract the sublist, and the copy it back. Yes, I know, this isn’t in-place either but short of rewriting Sort you won’t find such a solution.

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


If you can find a way to make use of some filter tools with the list or linq methods you can. Here is an example using the FindAll.

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


Do you have a requirement that the list needs to still have all items after this, or will you only be working on the subset that is ordered? If the latter then you can use regular Linq to do this - something like this might work for you.

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

This method will not change the original list however - it will just return a new IEnumerable that has only the sorted portion of the List.

As an alternate (if all data needs to remain in the list you could remove the subset that needs to be sorted, sort it then reattach it to the original list

0

精彩评论

暂无评论...
验证码 换一张
取 消