0
$\begingroup$

This may be a simple syntax question, but for some reason I've been having trouble with it. Suppose we have an array arr, and we want to set one of the elements to a particular value (say, 7). It's easy to do this manually:

arr = {{1, 2}, {3, 4}};
arr[[1, 2]] = 7;
arr

Out: {{1, 7}, {3, 4}}

How do we do this when the index we want to modify is stored as a list? It's easy to use Extract to return the current element at that location:

indices = {2, 2};
Extract[arr, indices]

Out: 4

But attempting to set it equal to a value (say, 13) gives errors:

Extract[arr, indices] = 13

Out: Set::write: Tag Extract in Extract[{{1,7},{3,4}},{2,2}] is Protected. >>

Similarly, using Part gives errors when done the naive way:

arr[[##]] & @@ indices = 13

Out: Set::write: Tag Apply in (arr[[##1]]&)@@{2,2} is Protected. >>

Of course, I can sort of do it manually in the following way:

arr[[indices[[1]], indices[[2]]]] = 13
arr

Out: {{1, 7}, {3, 13}}

But this becomes cumbersome when dealing with arrays which are very deep. So the question is, is there a way to set an element in an array to a value without having to enter the expression manually?

$\endgroup$
  • $\begingroup$ Try (arr[[#1, #2]] = 13;) & @@ indices? $\endgroup$ – Leo Fang May 21 '14 at 22:14
  • 1
    $\begingroup$ @LeoFang ## will do too. $\endgroup$ – Kuba May 21 '14 at 22:21
  • $\begingroup$ Yup, seems right- using arr[[##]] = 13; & @@ indices seems to be easies. $\endgroup$ – DumpsterDoofus May 21 '14 at 22:25
  • $\begingroup$ @Kuba, cool! Thanks. $\endgroup$ – Leo Fang May 21 '14 at 22:27
3
$\begingroup$

Single level indices (your example):

arr = {{1, 2}, {3, 4}}; indices = {2, 2};
(arr[[#1, #2]] = 13;) & @@ indices
arr

{{1, 2}, {3, 13}}

Double level indices (in case you need to replace more than one element)

arr = {{1, 2}, {3, 4}}; indices = {{1, 2}, {2, 2}}; newValues = {56, 78};
(arr[[#1, #2]] = newValues[[Position[indices, {#1, #2}][[1, 1]]]];) & @@@ indices
arr

{{1, 56}, {3, 78}}

$\endgroup$
2
$\begingroup$

another approach:

arr = {{1, 2}, {3, 4}};
indices = {{1, 2}, {2, 2}};
newValues = {56, 78};

arr = ReplacePart[arr, Thread[indices -> newValues]]
{{1, 56}, {3, 78}}

or

(arr[[##2]] = #) & @@@ Join[List /@ newValues, indices, 2];
arr
{{1, 56}, {3, 78}}
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.