在SWI序言中同时应用地图和过滤器?

时间:2019-03-30 19:02:40

标签: dictionary filter prolog

我有以下谓词:

 checkMachinePenaltiesRange(MachinePenaltiesArray):-
                         maplist(atom_chars , MachinePenaltiesArray, ListOfLists),
                         writeln(ListOfLists),
                         maplist( exclude(isSpace,X,NoSpacesArray) ,ListOfLists,ListOfLists1),
                         writeln(ListOfLists1).

% Helper function for exclude predicate
isSpace(X):- X == '',!.

我通过以下方式应用它:

checkMachinePenaltiesRange([1 1 1 1 1 1 1 1, 1 2 3 4 5 6 7 8, 1.3 1 1 1 1 1 1 1])

首先将此列表映射到列表列表,如下所示:

[[1,,1,,1,,1,,1,,1,,1,,1,], [1,,2,,3,,4,,5,,6,,7,,8], [1.3,,1,,1,,1,,1,,1,,1,,1]]

然后我想删除所有空格,所以结果是:

[[1,1,1,1,1,1,1,1], [1,2,3,4,5,6,7,8], [1.3,1,1,1,1,1,1,1]]

但是,exclude(过滤谓词)不想与maplist一起使用以获得我想要的结果。这两个怎么合并?

1 个答案:

答案 0 :(得分:2)

从前,findall / 3是选择的 列表处理,并且当您只有一个一个列表并包含从 one 计算的元素时>输入,它比maplist / 3更容易,因为您可以“内联”目标,并且它自然也可以充当过滤器。您只需要member / 2即可扫描输入,模式(第一个参数)将填充结果。例如

isSpace(' '). % note: no cut needed, and test 'pushed' in the head

checkMachinePenaltiesRange(MachinePenaltiesArray, ListOfLists1):-
    findall(List, (member(I,MachinePenaltiesArray),
                atom_chars(I,Cs),
                findall(C,(member(C,Cs),\+isSpace(C)),List)
               ),ListOfLists1).

checkMachinePenaltiesRange_OP(MachinePenaltiesArray,ListOfLists1):-
    maplist(atom_chars,MachinePenaltiesArray,ListOfLists),
    maplist(exclude(isSpace),ListOfLists,ListOfLists1).

您可以在checkMachinePenaltiesRange_OP / 2中看到您清除了示例代码,并比较了它们之间的差异。但是输出不会那么有用。从空格分隔的文本中删除空格很少是聪明的事情。当列表中有浮点数(例如1.3)时,就需要恢复它们……真是痛苦。如果您可以控制间距,则可以考虑

?- atomic_list_concat(L,' ','1.3 1 1 1 1 1 1 1').
L = ['1.3', '1', '1', '1', '1', '1', '1', '1'].