Assuming that I have a list of tuples that resemble the following example:
[(5, "a"), (1, "c"), (7, "d")]
in Elm, how do I go about sorting the list in ascending order by their first elements so that we get the following result?
[(1, "c"), (5, "a"), (7, "d")]
Using the Elm List documentation, it appears that the sortBy
and sortWith
functions will be useful for this case. My attempt at an implementation is as follows:
maxTuples : Tuple(a, b) -> Tuple(a, b) -> Tuple(a, b)
maxTuples t1 t2 =
case compare t1 t2 of
((Tuple.first t1) >= (Tuple.first t2)) -> GT
_ -> LT
sortByFirst : List (Tuple (a, b)) -> List (Tuple (a, b))
sortByFirst lst =
List.sortWith maxTuples lst
However, I'm getting compiler errors of the following nature:
I ran into something unexpected when parsing your code!
99| ((Tuple.first t1) >= (Tuple.first t2)) -> GT
^
I am looking for one of the following things:
an upper case name
My hunch would be that the compiler is looking for GT
/LT
/EQ
per the API of List
library, but if this the case I'm not sure how we would be able to use either sortBy
or sortWith
to sort a list of Tuples in Elm by the first index of each element.
You found the right functions. In your code, there are actually multiple problems:
(a, b)
, not Tuple(a, b)
.t1
with t2
, which will compare the tuples lexicographically. You actually want compare (Tuple.first t1) (Tuple.first t2)
case
branches require a pattern before the ->
. In this case would be something like EQ
, since you are matching on the result of compare
, which returns Order
type.You could fix the code like this:
maxTuples : (comparable, b) -> (comparable, b) -> (comparable, b)
maxTuples t1 t2 =
case compare (Tuple.first t1) (Tuple.first t2) of
GT -> GT
EQ -> EQ
_ -> LT
But now there is an unnecessary repetition, you are simply returning the result of compare
function.
maxTuples t1 t2 =
compare (Tuple.first t1) (Tuple.first t2)
Together with the sort function, it would look like this:
sortByFirst lst =
List.sortWith (\t1 t2 -> compare (Tuple.first t1) (Tuple.first t2)) lst
It turns out this kind of operation is quite common, especially with lists of records. For this reason, Elm offers another function – sortBy
. It takes a function and compares the elements after applying the function:
sortBy f lst =
List.sortWith (\a b -> compare (f a) (f b)) lst
You can therefore use sortBy
function to greatly simplify the code:
sortByFirst : List (comparable, b) -> List (comparable, b)
sortByFirst =
sortBy Tuple.first
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