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?
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.
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.
IEnumerable/IEnumerable<T> makes no guarantees about ordering, but the implementations that use IEnumerable/IEnumerable<T> may or may not guarantee ordering.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With