我想将对列表转换为两个列表 - 首先包含对的第一个元素,第二个包含对的第二个元素。
E.g。
[['Test1', 'US'], ['Test1', 'France'], ['Test2', 'German']]
应该产生
List1 = ['Test1', 'Test1', 'Test2']
List2 = ['US', 'France', 'German']
我尝试使用foreach
并提出此功能:
testfor:-
List = [['Test1', 'US'], ['Test1', 'France'], ['Test2', 'German']],
(
foreach(X,List) do
X=[F,S],
append([F],[],List1),
append([S],[],List2)
),
writeln(List1).
它不起作用,我很困惑。我在哪里弄错了?当然,您可以使用您的方法帮助我实现此功能(即“不要使用foreach
”)。
答案 0 :(得分:1)
好
yoba( [], [], [] ).
yoba( [[Name1, Name2] | Tail], List1, List2 ) :-
append( [Name1], ListNew1, List1 ),
append( [Name2], ListNew2, List2 ),
yoba( Tail, ListNew1, ListNew2 ).
和
?- yoba([['Test1', 'US'], ['Test1', 'France'], ['Test2', 'German']], X, Y).
X = ['Test1', 'Test1', 'Test2'],
Y = ['US', 'France', 'German'].
答案 1 :(得分:1)
pairs_to_lists([], [], []).
pairs_to_lists([E1-E2 | Tail], [E1 | Tail1], [E2 | Tail2]) :-
pairs_to_lists(Tail, Tail1, Tail2).
用法:
?- pairs_to_lists(['Test1'-'US', 'Test1'-'France', 'Test2'-'German'], L1, L2).
L1 = ['Test1', 'Test1', 'Test2'],
L2 = ['US', 'France', 'German'].
一些意见:
[A, B]
使用A-B
或pair(A, B)
。append([A], L1, L2)
与L2 = [A | L1]
相同,后者更具可读性。答案 2 :(得分:1)
使用maplist/4
,隐藏整个迭代,你必须考虑一对的解构。
%zip(?FirstList, ?SecondList, ?PairList)
zip(Fst, Snd, Pair) :- maplist(pair, Fst, Snd, Pair).
%pair(?First, ?Second, ?Pair)
pair(Fst, Snd, [Fst, Snd]).
因此使用它:
?- zip(List1, List2, [['Test1', 'US'], ['Test1', 'France'], ['Test2', 'German']]).
List1 = ['Test1', 'Test1', 'Test2'],
List2 = ['US', 'France', 'German'].
请注意,这是一个高级解决方案。首先,了解基本的递归解决方案(由其他答案提供)非常有用,我推荐它。没有很好地掌握递归,Prolog只是一个大地狱。实际上,maplist
也使用递归,它只是从调用者隐藏。
要学习的另一件事是Prolog的术语和统一是如何运作的。
append
。此外,它在性能和可读性方面都是有害的。使用仿函数可以更好地表示对,例如对['Test1', 'US']
变为pair('Test1', 'US')
。除了其他好处之外,偶然混淆对和三胞胎更难。使用仿函数有点类似于使用其他语言的类型。
SWI-Prolog使用连字符减号作为pairs的函子。由于具有operator declaration,连字符 - 减号也可用于中缀符号。例如。对['Test1', 'US']
变为'Test1'-'US'
。中缀表示法只是用于其他仿函数的通常前缀表示法的语法糖(即'Test1'-'US' == -('Test1', 'US')
)。
最后,您尝试使用的foreach ... do
符号看起来像loop construct from ECLiPSe,这是一种源自Prolog的语言。 SWI-Prolog不支持这种语法。
答案 3 :(得分:0)
testfor([], [], []).
testfor([[X, Y]|T1], [X|T2], [Y|T3]):-testfor(T1, T2, T3).