如何对包含[[A,B,2000],[C,D,2008],[F,G,2004]]
的列表列表进行排序
基于每个列表中的最后一个元素,并返回前两个元素,如上例所示。那是[[A,B],[F,G],[C,D]]
。
答案 0 :(得分:2)
请注意,以大写字母开头的单词是变量,而不是原子。从问题陈述中不清楚它是否意图列表元素是变量。我会假设它们是变量,因为它不会影响建议的解决方案。
可能有很多方法可以做到这一点,但这里有一种方法,我不认为是最佳方式:
1)使用setof
以不同的顺序收集排序的值。也就是说,将您的列表收集为一个如下所示的新列表:[[2000,A,B],[2004,F,G],[2008,C,D]]
。这假定每个列表项都是唯一的(没有所需的重复项)。
2)编写一个通过新列表的简单谓词,并删除每个子列表的第一个元素。
最终解决方案如下:
process( L, Result ) :-
setof([Z,X,Y], member([X,Y,Z], L), SortL), % gives list like shown above
stripyear(SortL, Result).
stripyear
是一个谓词,它将遍历每个列表项并去除年份(每个子列表的第一个元素)。它非常简单,遵循基本的Prolog列表处理原则:
stripyear([[_,B,C]|T1], [[B,C]|T2]) :-...
这里主要条款的头部说如果我的输入是一个看起来像[[_,B,C]|T1]
的列表,那么输出就是一个看起来像[[B,C]|T2]
的列表。也就是说,第二个列表的头部是第一个列表的头部,其第一个元素被删除。我们不关心该元素的价值,因此我们使用_
来显示它。但接下来我们需要处理T1
和T2
。它们有什么关系?我已经照顾好了头脑。尾部以相同的方式递归相关:第二个列表的尾部是第一个列表的尾部,其中删除了年份(第一个子列表元素):stripyear(T1, T2)
。所以完整的主要条款如下:
stripyear([[_,B,C]|T1], [[B,C]|T2]) :- stripyear(T1, T2).
这很棒,但它是如何停止的?如果我有一个空列表(striplist([], ?)
)怎么办?列表[]
与[[_,B,C]|T1]
不匹配,因为它没有头部或尾部。它是空的。如果没有处理它的条款,striplist([], Result)
就会失败。所以我需要一个子句来单独处理它,它也总结了递归:
stripyear([], []).
这说明如果我从空列表中剥离年份,我会得到一个空列表。很合乎逻辑。