Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deferred OrderBy on IEnumerable<T>

I have this code which just simply sorts IEnumerable of integers based on digit number in each of the integer.

var ints = new List<int>() { 66, 7, 9, -5, -22, 67, 122, -333, 555, -2 };
var ordered = ints.OrderBy(x =>
{
   x = Math.Abs(x);

   Console.WriteLine($"Getting length of {x}");

   int len = 0;
   while (x >= 1)
   {
      len++;
      x /= 10;
   }
   return len;
});

   Console.WriteLine("After OrderBy");
   Console.WriteLine("Fetching first item in ordered sequence");
   Console.WriteLine($"First item is {ordered.First()}");

   Console.WriteLine(string.Join(" ", ordered));

So, when the program hits line with fetching first item in ordered sequence in that moment the IEnumerable is getting sorted(I'm receiving output lines Getting lenght of XXX) because OrderBy was deferred and that't quite clear.

But why when program hits Console.WriteLine(string.Join(" ", ordered)); I'm again getting this output? Is IEnumerable sorted again? (isn't it already sorted?)

like image 294
monoh_ Avatar asked Jan 24 '26 09:01

monoh_


1 Answers

When you assign the value to ordered, they are not actually ordered. It's basically an instruction to order a list. IOrderedEnumerable<int>. So each time you try to access the first item, or any other item, it will convert this to an ordered list, to give you that item. The first time when you run .First(), and the second time when you run string.Join.
In both cases the program will create 2 distinct instances of an ordered list, use it up, then dispose of it by losing the reference (since you're not saving it).

like image 109
Alex Avatar answered Jan 25 '26 23:01

Alex