Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does Enumerable.OrderBy use keySelector

Tags:

c#

linq

Using the proceeding code, I successfully managed to produce a collection of numbers and shuffle the elements' position in the array:

var randomNumbers = Enumerable.Range(0, 100)
                    .OrderBy(x => Guid.NewGuid());

Everything functions fine but it's kind of thrown a spanner in my works when trying to understand Enumerable.OrderBy. Take the following code for example:

var pupils = new[] 
{ 
    new Person() { Name = "Alex", Age = 17 },
    new Person() { Name = "Jack", Age = 21 } 
};

var query = pupils.OrderBy(x => x.Age);

It's my understanding that I am passing the property I wish to sort by and I presume that LINQ will use Comparer<T>.Default to determine how to order the collection if no explicit IComparer is specified for the second overload. I really fail to see how any of this reasonable logic can be applied to shuffle the array in such a way. So how does LINQ let me shuffle an array like this?

like image 913
Caster Troy Avatar asked Jan 02 '13 08:01

Caster Troy


People also ask

How does OrderBy work in LINQ?

In the LINQ-OrderBy method, it supports both query and method syntax. Let's see the query syntax with examples. OrderBy sorts the values of a collection in ascending or descending order. It sorts the collection in ascending order by default because ascending keyword is optional here.

How does OrderBy work in C#?

In a query expression, the orderby clause causes the returned sequence or subsequence (group) to be sorted in either ascending or descending order. Multiple keys can be specified in order to perform one or more secondary sort operations. The sorting is performed by the default comparer for the type of the element.

Is enumerable ordered?

IEnumerable/IEnumerable<T> makes no guarantees about ordering, but the implementations that use IEnumerable/IEnumerable<T> may or may not guarantee ordering.


1 Answers

How does Enumerable.OrderBy use keySelector?

Enumerable.OrderBy<T> lazily returns - keySelector is not called directly. The result is an IOrderedEnumerable<T> that will perform the ordering when enumerated.

When enumerated, keySelector is called once for each element. The order of the keys defines the new order of the elements.

Here's a nifty sample implementation.


So how does LINQ let me shuffle an array like this?

var randomNumbers = Enumerable
  .Range(0, 100)
  .OrderBy(x => Guid.NewGuid());

Guid.NewGuid is called for each element. The call for the second element may generate a value higher or lower than the call for first element.

randomNumbers is an IOrderedEnumerable<int> that produces a different order each time it is enumerated. KeySelector is called once per element each time randomNumbers is enumerated.

like image 118
Amy B Avatar answered Sep 17 '22 14:09

Amy B