Pregunta

Necesito ordenar las tuplas de acuerdo con el segundo elemento de cada tupla, pero aparentemente usort / 1 solo funciona con el primer elemento. Así que tengo que intercambiar los elementos, ordenarlos y volver a cambiar. ¿Hay alguna manera más fácil? También hay una forma de ordenar en orden descendente (sé que se puede ordenar e invertir, pero solo quiero saber).

¿Fue útil?

Solución

¿Has probado la función keysort / 2 (o su contraparte ukeysort / 2 )?

> lists:reverse(lists:keysort(2, [{a,2}, {b,1}, {c, 3}])).
[{c,3},{a,2},{b,1}]

Si no ordena listas muy grandes, esta es probablemente la solución más legible que puede obtener.

Otros consejos

En realidad, una mejor respuesta:

Hay una segunda versión de sort que toma una función de clasificación:

lists:sort(Fun, List1) -> List2

Aquí hay un ejemplo que se ordena en el segundo elemento de una tupla:

lists:sort(fun(A, B) ->
                   {A1, A2} = A,
                   {B1, B2} = B,
                   if
                       A2 > B2 ->
                           false;
                       true ->
                           true
                   end
           end, YourList).

Una versión mejorada de la solución de bmdhacks:

lists:sort(fun(A, B) ->
                   {_, A2} = A,
                   {_, B2} = B,
                   A2 =< B2
           end, YourList).

Los guiones bajos son mejores que A1 y B1, porque el compilador dará advertencias para aquellos.

Para ordenar en orden descendente, simplemente cambie < = a > =.

No debería ser demasiado difícil escribir su propia función de clasificación (adaptada de un ejemplo común):

qsort([]) -> [];
qsort([Pivot|Tail]) ->
    {PivotFirst, PivotSecond} = Pivot,
    qsort([{FirstElement, SecondElement} || {FirstElement,SecondElement} <- Tail, SecondElement < PivotSecond])
        ++ [Pivot] ++
        qsort([{FirstElement, SecondElement} || {FirstElement,SecondElement} <- Tail, SecondElement >= PivotSecond]).
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top