I need do this:
replace(L,P,E,R)
, where L is the current list, P is the position where the element will be insert, E is the element to insert and R is the return, the new list.
Example:
L = [1,2,3,4,5],
replace(L,2,'@',R).
R = [1,2,'@',4,5]
I tried this, but nothing happens, the list continuous to be the same:
replaceInThePosition([_|T],1,E,[['1',E]|T]).
replaceInThePosition([H|T],P,E,[H|R]) :-
P > 0, NP is P-1, replaceInThePosition(T,NP,E,R), !.
You're not far.
You can try with
replaceInThePosition([_|T],0,E,[E|T]).
replaceInThePosition([H|T],P,E,[H|R]) :-
P > 0, NP is P-1, replaceInThePosition(T,NP,E,R).
I mean:
1) 0
instead 1
in the first clause (or 1
in the first clause but P > 1
in the second one; but in this case from replaceInThePosition([1, 2, 3, 4, 5], 2, '@', R)
you unify R = [1, @, 3, 4, 5]
, not R = [1, 2, @, 4, 5]
)
2) [E|T]
for the last ergument in the first clause, not [['1',E]|T]
3) no cut (no !
) at the end of the second clause (there is no need: the first clause i when P
is zero; the secon one when P > 0
; so they are mutually exclusive
You could do this using append/3
:
substitute(L, P, E, R) :-
PreLen is P - 1,
length(PreLen, P1),
append(Pre, [_|T], L),
append(Pre, [E|T], R).
another possibility:
/*
L is the current list,
P is the position where the element will be insert,
E is the element to insert and
R is the return, the new list
*/
replaceInThePosition(L, P, E, R) :-
findall(X, (nth0(I,L,Y), (I == P -> X=E ; X=Y)), R).