Use a Condition
(/;
) to check the relation between the values of the pattern elements. You must also use RuleDelayed
(:>
) instead of Rule
(->
), since the rule now depends on the particular values of the matched pattern.
ReplacePart[{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, {i_, j_} :>
x /; i == j + 1]
(* {{0, 0, 0}, {x, 0, 0}, {0, x, 0}} *)
UPDATE: The erroneous-appearing result of the original code appears to be due to ReplacePart
checking the second argument to see if it is a list of parts to be replaced. If the first element of the list has depth (e.g. {1}
or _+1
), then ReplacePart
treats all elements of the list as parts to be replaced.
Consider:
(* Expected use *)
ReplacePart[Array[f, {3, 3}], {{1}, {2}, {0}} -> x]
(* x[x, x, {f[3, 1], f[3, 2], f[3, 3]}] *)
(* First element is nonsense *)
ReplacePart[Array[f, {3, 3}], {_+1, 1, 2, 0} -> x]
(* x[x, x, {f[3, 1], f[3, 2], f[3, 3]}] *)
(* First element doesn't exist *)
ReplacePart[Array[f, {3, 3}], {{7}, 1, 2, 0} -> x]
(* x[x, x, {f[3, 1], f[3, 2], f[3, 3]}] *)
SECOND EDIT: So to analyze the original case, the first element of the replacement-part list has nontrivial depth, so we treat each element as a part to be replaced. The first element is nonsense, so it matches nothing. The second element is a Blank
, so it matches all integers and all parts of the list are replaced by x
.
ReplacePart
. $\endgroup$