Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

swi-prolog: how to sort list of lists by NTH element of sublist, ALLOWING DUPLICATES

(I have used 'asserta' to put a large csv file with several columns into the database.) Is there a way to sort numerically by column without removing duplicates?

As you can see from my simple example (which sorts by the second column / element), the predsort method removes duplicates.

I could work around this by switching and removing some columns and using msort, but am asking you specifically here for an alternative.

Any advice would be v much appreciated !

mycompare(X,E1,E2):- 
E1=[_,A1],E2=[_,A2],compare(X, A1, A2).

?- predsort(mycompare,[ [[95, 97], 11], [[97, 99], 4], [[97, 98], 4]],X).
X = [[[97, 99], 4], [[95, 97], 11]].

?- msort([ [[95, 97], 11], [[97, 99], 4], [[97, 98], 4]],X).
X = [[[95, 97], 11], [[97, 98], 4], [[97, 99], 4]].

%What I want is:
?- wanted_sort(...<as above>...).
X = [[[97, 98], 4], [[97, 99], 4], [[95, 97], 11] ].
like image 441
Andrew Avatar asked Aug 04 '14 17:08

Andrew


1 Answers

The standard way to do this would be to use keysort/2. So first you start by mapping the elements accordingly, then keysorting, and mapping back the values.

list_pairs([], []).
list_pairs([E|Es], [B-E|Ps]) :-
   E = [_,B],
   list_pairs(Es, Ps).

pairs_values([], []).
pairs_values([_-V|Ps], [V|Vs]) :-
   pairs_values(Ps, Vs).

andrew_sort(Xs, Ys) :-
   list_pairs(Xs, Ps),
   keysort(Ps, PsS),
   pairs_values(PsS, Ys).

For other uses of keysort/2 see this list.

like image 175
false Avatar answered Sep 26 '22 10:09

false