swi-prolog:如何按子列表的NTH元素对列表进行排序,允许重复

And*_*rew 5 sorting list prolog

(我使用'asserta'将带有多个列的大型csv文件放入数据库中.)有没有办法按列进行数字排序而不删除重复项?

正如您从我的简单示例(按第二列/元素排序)中所看到的,predsort方法可以删除重复项.

我可以通过切换和删除一些列并使用msort来解决这个问题,但我在这里特别要求您提供替代方案.

任何建议将非常感谢!

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] ].
Run Code Online (Sandbox Code Playgroud)

Cap*_*liC 2

Imho predsort /3 提供了一种非常通用且相当有效的方法 - 它就像避免=从比较谓词返回一样简单。例子:

?- [user].
|: comparer(<, A, B) :- A @< B.
|: comparer(>, _, _).
(^D here)
true.

?- predsort(comparer, [1,2,1,a,b,a], L).
L = [1, 1, 2, a, a, b].
Run Code Online (Sandbox Code Playgroud)

您的测试用例:

mycompare(<,[_,A1|_],[_,A2|_]) :- A1 < A2.
mycompare(>, _, _).
Run Code Online (Sandbox Code Playgroud)

产量

?- predsort(mycompare,[ [[95, 97], 11], [[97, 99], 4], [[97, 98], 4]],X).
X = [[[97, 98], 4], [[97, 99], 4], [[95, 97], 11]].
Run Code Online (Sandbox Code Playgroud)

我稍微概括了匹配的模式,从[_,N][_,N|_]...

编辑:这很有趣,我没有读标题......概括比较第 n 个参数:

?- predsort(nthcompare(2),[ [[95, 97], 11], [[97, 99], 4], [[97, 98], 4]],X).
X = [[[97, 98], 4], [[97, 99], 4], [[95, 97], 11]].
Run Code Online (Sandbox Code Playgroud)

和 nthcompare/4 本身:

nthcompare(N,<,A,B) :- nth1(N,A,X),nth1(N,B,Y), X @< Y.
nthcompare(_,>,_,_).
Run Code Online (Sandbox Code Playgroud)

那是...