Hi! I need to sort lists of lists according to their second element, i.e. an input {{1, 2}, {2, 2.5}, {3, 1.5}} should result in an output {{2, 2.5}, {1, 2}, {3, 1.5}}.

The first element of the sublists can be arbitrary (e.g. strings) and the second elements of the sublists are non-unique numbers, so they cannot be used for reverse indexing.

Is there a custom sort command for this on the HP Prime?

(01-20-2019 06:09 PM)EricR Wrote: [ -> ]Hi! I need to sort lists of lists according to their second element, i.e. an input {{1, 2}, {2, 2.5}, {3, 1.5}} should result in an output {{2, 2.5}, {1, 2}, {3, 1.5}}.

SORT({{1,2},{2,2.5},{3,1.5}},2) will return {{3,1.5},{1,2},{2,2.5}}.

If you want the second elements in descending order, just reverse the list:

REVERSE(SORT({{1,2},{2,2.5},{3,1.5}},2)) will return {{2,2.5},{1,2},{3,1.5}}

Didier,

The [sort _by] identifier works great in [Home] but not in [CAS], (Emulator):

[HOME]

SORT({{1,2},{2,2.5},{3,1.5}},2) ==> {{3,1.5},{1,2},{2,2.5}}

[Cas]

SORT({{1,2},{2,2.5},{3,1.5}},2) ==> {{3,1.5},{2,2.5},{1,2}}

-Dale-

The CAS sort function works differently than the HOME SORT function for the second argument, it should define a function to be used for the sorting.

In CAS :

sort({{1,2},{2,2.5},{3,1.5}},(x,y)->when(x[2] = y[2],x[1]>y[1],x[2]>y[2]))

returns:

{{2,2.5},{1,2},{3,1.5}}

The sorting is done on the second item in descending order, and if the second item is the same, on the first item also in descending order.

(01-20-2019 11:38 PM)Didier Lachieze Wrote: [ -> ]In CAS :

sort({{1,2},{2,2.5},{3,1.5}},(x,y)->when(x[2] = y[2],x[1]>y[1],x[2]>y[2]))

returns:

{{2,2.5},{1,2},{3,1.5}}

Another way is

Schwartian transformed sort.

For above case, assuming 1-based indexing, in X-Cas:

m := [[1,2], [2,2.5], [3,1.5]]

reverse(swapcol(sort(swapcol(m, 1,2)), 1,2)) --> [[2,2.5], [1,2], [3,1.5]]

(01-20-2019 11:38 PM)Didier Lachieze Wrote: [ -> ]The CAS sort function works differently than the HOME SORT function for the second argument, it should define a function to be used for the sorting.

In CAS :

sort({{1,2},{2,2.5},{3,1.5}},(x,y)->when(x[2] = y[2],x[1]>y[1],x[2]>y[2]))

returns:

{{2,2.5},{1,2},{3,1.5}}

The sorting is done on the second item in descending order, and if the second item is the same, on the first item also in descending order.

With only the provided hp documentation, using a function as the second argument isn't shown. In the original example, if sort() is given as the [CAS]command, it gets case-changed to SORT(), which doesn't work when the format used follows either the User Guide, or the on screen help guidance.

For the CAS side, perhaps SORT({{1,2},{2,2.5},{3,1.5}},2), should just return, "Error: Bad argument error."

Another approach could be to suggest: See XCAS help, (an external resource). This idea connects the CAS side with XCAS, and hints that the XCAS help could be useful for this, and perhaps other CAS needs.

(01-21-2019 03:05 AM)Albert Chan Wrote: [ -> ]Another way is Schwartian transformed sort.

For above case, assuming 1-based indexing, in X-Cas:

m := [[1,2], [2,2.5], [3,1.5]]

reverse(swapcol(sort(swapcol(m, 1,2)), 1,2)) --> [[2,2.5], [1,2], [3,1.5]]

Interesting. I have been using that method for years but never new it had a name.

(01-20-2019 11:38 PM)Didier Lachieze Wrote: [ -> ]In CAS :

sort({{1,2},{2,2.5},{3,1.5}},(x,y)->when(x[2] = y[2],x[1]>y[1],x[2]>y[2]))

Playing with the key compare function, noticed an odd behavior.

X-Cas logical operators (and, or) have the

same precedence.

a and b or c => (a and b) or c

a or b and c => (a or b) and c

So, above compare function using logical operator need an extra parenthesis:

(x,y) -> x[2]>y[2] or (x[2]==y[2] and x[1]>y[1])