【问题标题】:Replace one or more elements in a nested list替换嵌套列表中的一个或多个元素
【发布时间】:2017-06-14 00:39:12
【问题描述】:

我正在努力实现这一目标:

给定OldList,如果项目满足目标(oldNew),则替换任何项目;如果不是,请不要更换该项目。

返回一个 NewList,其中替换的项目与 OldList 具有相同的结构(即相同的嵌套)。

对于特殊情况OldList = [a, b, c],我让它工作(见我的代码),但我想写一个泛化列表长度和嵌套列表的谓词,例如也适用于OldList = [a, [b, c, [d, e]]]

提前致谢! /JC

oldNew(fruit, banana).
oldNew(car, ferrari).

replace(OldList, NewList):-
    [X1, X2, X3] = OldList,
    (oldNew(X1, Y1); Y1 = X1),
    (oldNew(X2, Y2); Y2 = X2),
    (oldNew(X3, Y3); Y3 = X3),
    (oldNew(X1, Y1); oldNew(X2, Y2), oldNew(X3, Y3)),
    NewList = [Y1, Y2, Y3].

编辑1:

让它适用于任意长度的列表;但我仍然不知道如何处理嵌套列表。

replace2(OldList, NewList):-
    [H | T] = OldList,
    oldNew(H, NewHead),
    NewList = [NewHead | T].
replace2(OldList, NewList):-
    [H | T] = OldList,
    replace2(T, NewTail),
    NewList = [H | NewTail].

【问题讨论】:

    标签: list replace prolog


    【解决方案1】:

    通常,模式匹配在头部明确。代码更清晰:

    replace2([], []).
    replace2([H|T], [Ht|Tt]) :-
      (  oldNew(H, Ht)
      -> true
      ;  is_list(H)
      -> replace2(H, Ht)
      ;  H = Ht
      ),
      replace2(T, Tt).
    

    在 SWI-Prolog 库中,applyyall 允许代码稍微短一些:

    replace2(L, T) :- maplist([H,Ht]>>
      (  oldNew(H, Ht)
      -> true
      ;  is_list(H)
      -> replace2(H, Ht)
      ;  H = Ht
      ), L, T).
    

    您可以看到括号中的析取已从以前的定义中复制和粘贴。这是一个 lambda 应用程序...

    ?- replace2([aa, car, apple, fruit, any, [aa, car, apple, banana, any]], T).
    T = [aa, ferrari, apple, banana, any, [aa, ferrari, apple|...]].
    

    【讨论】:

    • 很好地使用了applyyall
    猜你喜欢
    • 2017-07-05
    • 2021-06-15
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    • 2021-09-26
    • 2023-03-22
    • 2015-11-09
    • 1970-01-01
    相关资源
    最近更新 更多