Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sorting 从Prolog中的嵌套列表中排序/获取最大成员和id? 让我想想我有一些类似这样的发现: findall([ID, Val], (some_predicate(ID, Val), Val >= 50), XS)._Sorting_Prolog_Max_Nested Lists_Swi Prolog - Fatal编程技术网

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 ;
...