#erlang #sorting
Вопрос:
Мне нужно отсортировать кортежи в соответствии со вторым элементом каждого кортежа, но, по-видимому, usort/1 работает только с первым элементом. Поэтому я должен поменять местами элементы, использовать их и поменять местами обратно.Есть ли более простой способ?Также есть способ сортировки в порядке убывания (я знаю, что сортировку и реверсирование можно выполнить, но просто хочу знать).
Ответ №1:
Вы пробовали функцию keysort/2 (или ее аналог ukeysort/2)?
> lists:reverse(lists:keysort(2, [{a,2}, {b,1}, {c, 3}])).
[{c,3},{a,2},{b,1}]
Если вы не сортируете очень большие списки, это, вероятно, самое читаемое решение, которое вы можете получить.
Ответ №2:
На самом деле, лучший ответ:
Существует вторая версия сортировки, которая использует функцию сортировки:
lists:sort(Fun, List1) -> List2
Вот пример сортировки по второму элементу в кортеже:
lists:sort(fun(A, B) ->
{A1, A2} = A,
{B1, B2} = B,
if
A2 > B2 ->
false;
true ->
true
end
end, YourList).
Ответ №3:
Улучшенная версия решения bmdhacks:
lists:sort(fun(A, B) ->
{_, A2} = A,
{_, B2} = B,
A2 =< B2
end, YourList).
Подчеркивания лучше, чем A1 и B1, потому что компилятор будет выдавать предупреждения
для них.
Чтобы отсортировать в порядке убывания, просто измените <= на >=.
Ответ №4:
Не должно быть слишком сложно написать свою собственную функцию сортировки (адаптированную из общего примера).:
qsort([]) -> [];
qsort([Pivot|Tail]) ->
{PivotFirst, PivotSecond} = Pivot,
qsort([{FirstElement, SecondElement} || {FirstElement,SecondElement} <- Tail, SecondElement < PivotSecond])
[Pivot]
qsort([{FirstElement, SecondElement} || {FirstElement,SecondElement} <- Tail, SecondElement >= PivotSecond]).