我正在从列表中检索多个列表,并将它们放入一个新列表中。但我想做一个单独项目的新列表,而不是一个有列表的列表。假设我有列表[[a,b],c,[d,e]],我想得到[a,b,c,d,e]。我该怎么做?
要使用今天从一个随机问题中截取的代码示例:假设您有如下知识库:
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
是不允许的,您现在有两个选择:要么使结果变平,要么使用findall覆盖一道菜中每个step
的成分列表中的所有成分。
对于flatten,我建议使用本文中的实现flatten2/2
。由此产生的问题可能是这样的:
?- Dish='pancakes', findall(X,step(Dish,_,_,X,_),I), flatten2(I,J).
如果你想在这篇文章中消除重复,请添加一个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
。
附言:我还是不知道你是否被允许使用findall/3
。
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.
?-