Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OrderBy ThenBy in F#

Is there any function in F# similar to LINQ fluent syntax for sorting by multiple expressions:

myList.OrderBy(fun x->x.Something).ThenBy(fun x->x.SomethingElse)

I'd love something like:

myList 
|> Seq.sort_by(fun x->x.Something) 
|> Seq.then_by(fun x->x.SomethingElse)

Thx

like image 784
Luca Martinetti Avatar asked May 05 '09 18:05

Luca Martinetti


2 Answers

Use a tuple as your sort key:

myList |> Seq.sortBy (fun x -> x.Something, x.SomethingElse)
like image 91
Tim Robinson Avatar answered Oct 14 '22 11:10

Tim Robinson


Because sortBy is defined to be stable, you can sort multiple times, using the secondary key(s) in reverse order:

myList |> Seq.sortBy (fun x -> x.SomethingElse) |> Seq.SortBy (fun x -> x.Something)

Items that compare the same for the primary key will retain the previous ordering done by the secondary key. Items that compare the same for both keys will be in the original order. This has the advantage (unlike the tuple method) that you can control whether the sort is descending for each of the keys independently.

If your sort keys are signed integers and you wish to sort, say, the secondary key in descending order, you can still use the tuple method using negation:

myList |> Seq.sortBy (fun x -> x.Something, -x.SomethingElse)

This method is arguably less clear, but may be faster than sorting twice. Be aware that it does not correctly handle the smallest value correctly because of overflow.

like image 12
Rick Sladkey Avatar answered Oct 14 '22 13:10

Rick Sladkey