2017-01-28 7 views
1

Я пытаюсь добиться этого:Заменить один или несколько элементов в списке вложенного

Учитывая 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]. 

EDIT1:

Понял работать с произвольными длинами списка; но я до сих пор не знаю, как обрабатывать вложенные списки.

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

ответ

2

Обычно сопоставление образцов четко выражено в голове. Код понятнее:

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

В SWI-Prolog библиотек apply и yall позволяют немного более короткий код:

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

Вы можете увидеть в квадратных скобках дизъюнкция была копия и вставить из прежнего определения. Это приложение лямбда ...

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

Приятное использование 'apply' и' yall'. –

+0

Спасибо CapelliC, это решило мою проблему. – JCR

 Смежные вопросы

  • Нет связанных вопросов^_^