【发布时间】:2021-03-03 02:32:27
【问题描述】:
我正在从列表中检索多个列表并将它们放入一个新列表中。但我想制作单个项目的新列表,而不是带有列表的列表。所以说我有列表 [[a,b],c,[d,e]] 我想得到 [a,b,c,d,e]。我该怎么办?
【问题讨论】:
-
它是给学校的,我不能用 flatten 大声笑
-
那你应该告诉我们你尝试了什么,你卡在哪里了
我正在从列表中检索多个列表并将它们放入一个新列表中。但我想制作单个项目的新列表,而不是带有列表的列表。所以说我有列表 [[a,b],c,[d,e]] 我想得到 [a,b,c,d,e]。我该怎么办?
【问题讨论】:
flatten(SOURCEs,TARGETs)
:-
phrase(flatten(SOURCEs),TARGETs)
.
flatten([HEAD|TAILs]) --> { is_list(HEAD) } , HEAD , flatten(TAILs) .
flatten([HEAD|TAILs]) --> { \+ is_list(HEAD) } , [HEAD] , flatten(TAILs) .
flatten([]) --> [] .
/**
?- flatten([[a,b],c,[d,e]],TARGETs) .
TARGETs = [a, b, c, d, e] ;
false.
?-
【讨论】:
使用今天从一个随机问题中截取的示例代码:假设您有如下知识库:
step('pancakes', 1, 'mix butter and sugar in a bowl', [butter, sugar], [bowl]).
step('pancakes', 2, 'add eggs', [eggs], []).
step('pancakes', 3, 'mix flour and bakingpowder', [flour, bakingpowder], []).
你对一道菜的所有配料感兴趣。第一个想法是
?- Dish='pancakes', findall(X,step(Dish,_,_,X,_),I).
Dish = pancakes,
I = [[butter, sugar], [eggs], [flour, bakingpowder]] ;
false.
但这里的问题是配料表是嵌套的。由于不允许使用 flatten/2,因此您现在有 2 种选择:要么将结果变平,要么使用每个 step 的成分列表中的所有成分来查找菜肴。
对于扁平化,我建议使用来自this 帖子的实现flatten2/2。由此产生的问题可能是这样的:
?- Dish='pancakes', findall(X,step(Dish,_,_,X,_),I), flatten2(I,J).
如果您想删除 this 帖子中声明的重复项,请添加 sort/2。
如果你想使用第二种方法,你必须创建一个辅助谓词来显示所有菜肴的成分。 ingredients/3 将配料作为每道菜和步骤编号的单个元素。因此,对于每个 Dish 和 Step,可以使用不同成分的多个条目。
ingredients(Dish,Step,Ingred):-
step(Dish,Step,_,L,_),
member(Ingred,L).
?- Dish='pancakes', findall(X,ingredients(Dish,_,X),I).
Dish = pancakes,
I = [butter, sugar, eggs, flour, bakingpowder] ;
false.
要删除重复项,请使用sort/2。
PS:我还是不知道你是否可以使用findall/3。
【讨论】: