我再次陷入了一个非常简单的Prolog任务。我想定义一个谓词kv_search/3
,该谓词将一个键/值列表(例如[[a,1],[b,2],[c,3],[d,4],[e,8],[a,9],[b,10]]
作为第一个参数,将一个键作为第二个参数,并输出在第三个参数中具有该键的所有值的列表。 / p>
我当前的方法如下:
kv_find([[K,V|_]|Rest], K, Result) :-
kv_find(Rest, K, [V|Result]).
kv_find([[Ks,_|_]|Rest], K, Result) :-
Ks \= K ,
kv_find(Rest, K, Result).
kv_find([], _, _).
但是,此解决方案的问题在于它仅输出true或false,而不输出缺少的参数。
例如以下查询结果来自true
,而不是我的预期结果B=[1, 9]
:
kv_find([[a,1],[b,2],[c,3],[d,4],[e,8],[a,9],[b,10]], a, B).
如果该键不存在于列表中,我想输出一个空列表。
答案 0 :(得分:4)
首先,您的基本情况是错误的,您需要编写:
kv_find([], _, []).
由于列表为空,因此只有一个空的输出列表才能成功。
然后您的解决方案中的另一个问题是您正在编写:
kv_find([[K,V|_]|Rest], K, Result) :-
kv_find(Rest, K, [V|Result]).
尽管您应该编写类似的内容:
kv_find([[K,V|_]|Rest], K, [V | Result]) :-
kv_find(Rest, K, Result).
上面的规则使用了错误的基本情况,使您的谓词对于任何第三个列表而言总是成功的。
此外,我做了一些改动,例如:
kv_find([[K,V]|Rest], K, [V|Result]) :-
kv_find(Rest, K, Result).
kv_find([[Ks,_]|Rest], K, Result) :-
dif(Ks, K) ,
kv_find(Rest, K, Result).
kv_find([], _, []).