Сортировка списка кортежей по их вторым элементам

Я хочу отсортировать список кортежей по их вторым элементам.

Пример ввода:

[("Bob",3),("Terry",1)]

Пример вывода:

[("Terry",1)("Bob",3)]

Ответ 1

Еще один классный трюк - использовать on из Data.Function:

import Data.Function (on)
import Data.List (sortBy)

sortBy (compare `on` snd) [...]

Не сильно отличается от comparing, но время от времени приятный трюк.

Ответ 2

Вы можете использовать sortBy и comparing:

sortBy :: (a -> a -> Ordering) -> [a] -> [a]
comparing :: (Ord b) => (a -> b) -> a -> a -> Ordering

В этом случае мы хотим сравнить второй элемент. Вы можете использовать comparing snd для получения функции, которая может сравнивать два кортежа со своим вторым элементом.

Ответ 3

Рассмотрим "регулярный" вид

sort xs = ... a < b ...

Такие типы должны использовать compare или его друзей, например <. Поэтому, если вы уже реализовали такую ​​вещь, вместо вместо compare a b или a < b вы можете сделать compare (snd a) (snd b) или snd a < snd b.

sort xs = ... snd a < snd b ...

Конечно, если вы умны, вы абстрагируете "accessor" и делаете его дополнительным входом в функцию сортировки:

sortComparingOn f xs = ... f a < f b ...

Вы даже можете полностью исключить компаратор:

sortBy cmp xs = ... a `cmp` b ...

sortBy предоставляется в Data.List, как указано выше.