(我使用'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] ].
答案 0 :(得分:2)
执行此操作的标准方法是使用keysort/2
。首先,您首先相应地映射元素,然后键入,并映射回值。
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).
对于keysort/2
的其他用途,请参阅this list。
答案 1 :(得分: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].
您的测试用例:
mycompare(<,[_,A1|_],[_,A2|_]) :- A1 < A2.
mycompare(>, _, _).
产量
?- predsort(mycompare,[ [[95, 97], 11], [[97, 99], 4], [[97, 98], 4]],X).
X = [[[97, 98], 4], [[97, 99], 4], [[95, 97], 11]].
我略微概括了匹配的模式,从[_,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]].
和nthcompare / 4本身:
nthcompare(N,<,A,B) :- nth1(N,A,X),nth1(N,B,Y), X @< Y.
nthcompare(_,>,_,_).
那是......