Sorting 从Prolog中的嵌套列表中排序/获取最大成员和id? 让我想想我有一些类似这样的发现: findall([ID, Val], (some_predicate(ID, Val), Val >= 50), XS).
这将在列表(或元组)列表中结束,如: 如何按值(降序)对列表进行排序 最后,我想得到以下信息:Sorting 从Prolog中的嵌套列表中排序/获取最大成员和id? 让我想想我有一些类似这样的发现: findall([ID, Val], (some_predicate(ID, Val), Val >= 50), XS).,sorting,prolog,max,nested-lists,swi-prolog,Sorting,Prolog,Max,Nested Lists,Swi Prolog,这将在列表(或元组)列表中结束,如: 如何按值(降序)对列表进行排序 最后,我想得到以下信息: [Max|RS] = SortedByValue. Max = [8, 287], RS = [[11, 157], [3, 102], [2, 51]]. 如果您创建一个谓词来转换成对列表中两个元素的列表(观察:一个双向工作的谓词),则反转成对的顺序 listPairConverter([], []). listPairConverter([[K, V] | Ti], [V-K | To]) :
[Max|RS] = SortedByValue.
Max = [8, 287],
RS = [[11, 157], [3, 102], [2, 51]].
如果您创建一个谓词来转换成对列表中两个元素的列表(观察:一个双向工作的谓词),则反转成对的顺序
listPairConverter([], []).
listPairConverter([[K, V] | Ti], [V-K | To]) :-
listPairConverter(Ti, To).
和一个谓词,用于反转列表
reverseList([], Rl, Rl).
reverseList([H | T], Rl, Acc) :-
reverseList(T, Rl, [H | Acc]).
使用iso谓词keysort/2
,您可以编写一个谓词,根据内部列表的第二个元素对列表进行排序,如下所示
sortValue(Li, Lo) :-
listPairConverter(Li, R0),
keysort(R0, R1),
listPairConverter(R2, R1),
reverseList(R2, Lo, []).
这么叫
sortValue([[2, 51], [3, 102], [8, 287], [11, 157]], Lo)
您可以将Lo
与
[[8,287],[11,157],[3,102],[2,51]]
如果要按值排序,是否必须先使用
Id
对数据对进行排序?如果你不这样做就容易多了setof/3
将按其第一个分量按升序排列对,然后您可以反转它们:
max_rest(MaxPair, RS) :-
setof([Val, Id], (some_predicate(Id, Val), Val >= 50), XS),
reverse(XS, [MaxPair | RS]).
如果您确实需要首先使用Id
获取结果,您可以重新映射它们:
swap([A, B], [B, A]).
max_rest(MaxPair, RS) :-
setof([Val, Id], (some_predicate(Id, Val), Val >= 50), XValIds),
maplist(swap, XValIds, XIdVals),
reverse(XIdVals, [MaxPair | RS]).
您的问题完全符合库()中的要求: 该库非常新,因为我以前从未使用过它,我通过以下测试步骤获得了该结果:
?- [library(solution_sequences)].
true.
?- [user].
some_predicate(ID,Val) :- member([ID,Val],[[2, 51], [3, 102], [8, 287], [11, 157]]).
|: (^D here)true.
?- order_by([desc(Val)], (some_predicate(ID, Val), Val >= 50)).
Val = 287,
ID = 8 ;
Val = 157,
ID = 11 ;
...
您可以使用
maplist/3
以一种很好的方式实现列表对转换器。定义list\u对([A,B],A-B)。
然后使用maplist(list\u对,list,Pairs)。
@潜伏者:为什么不使用库(yall)<代码>地图列表([[A,B],A-B]>>正确,列表,成对)。@capelical那就更好了。我没有考虑library(yall)
,这么好的评论。不,我不需要这个确切的顺序,它只是我数据库中的自然顺序。然而,重新映射以获得原始订单是一个不错的附加组件!谢谢
?- findall([ID, Val], order_by([desc(Val)], (some_predicate(ID, Val), Val >= 50)), [Max|Rs]).
Max = [8, 287],
Rs = [[11, 157], [3, 102], [2, 51]].
?- [library(solution_sequences)].
true.
?- [user].
some_predicate(ID,Val) :- member([ID,Val],[[2, 51], [3, 102], [8, 287], [11, 157]]).
|: (^D here)true.
?- order_by([desc(Val)], (some_predicate(ID, Val), Val >= 50)).
Val = 287,
ID = 8 ;
Val = 157,
ID = 11 ;
...