I want to understand how ThenBy works in .Net. (I know how to use it, I just don't understand how Microsoft implemented it!)
According to the documentation, string_list.OrderBy(Function (x) x.length).ThenBy(Function (x) x)
should output a list of strings ordered by length and then alphabetically. How could it possibly work?!? The first sort is by length. The second sort should undo the sorting of the first one!
Assume this code:
Dim sorted_by_length As IOrderedEnumerable(Of String)
sorted_by_length = string_list.OrderBy(Function (x) x.length)
sorted_by_length = sorted_by_length.ThenBy(Function
Here's me trying to implement the last line without using ThenBy
:
Dim sorted_by_length As IOrderedEnumerable(Of String)
sorted_by_length = string_list.OrderBy(Function (x) x.length)
'my implementation of OrderBy:
Dim e as IEnumerator(Of String) = sorted_by_length.GetEnumerator
Do While e.MoveNext
'I have no idea what to write here!
Loop
There's some magic going on here... Is there some e.GetPreviousKeySelector() function? In fact, I can't even write a function that returns IOrderedEnumerable!
C# LINQ C# linq. LINQ ThenBy Operator is used when we want to sort the elements in a collection by using multiple properties in ascending order. This operator must use after OrderBy or OrderByDescending operator.
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.
Yes, they're definitely stable.
Sorts the elements of a sequence in ascending order according to a key. OrderBy<TSource,TKey>(IEnumerable<TSource>, Func<TSource,TKey>, IComparer<TKey>) Sorts the elements of a sequence in ascending order by using a specified comparer.
How could it possibly work?!? The first sort is by length. The second sort should undo the sorting of the first one!
No, the second sort comparison is only consulted when the primary comparison finds two equal values.
The IOrderedEnumerable
implementation does this by remembering all the comparisons, effectively - or, as another way of putting it, allowing you to build a comparison from "the current comparison and another one to consult when that returns 0".
I have a blog post series which goes into LINQ to Objects in some depth, providing a complete alternative implementation. The basis of IOrderedEnumerable
is covered in part 26a and 26b, with more details and optimization in 26c and 26d.
In fact, I can't even write a function that returns IOrderedEnumerable!
You absolutely can - either by returning the value returned from OrderBy
, or by implementing it yourself.
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