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

2 Answers 2

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 and acknowledge that you have read and understand our privacy policy and code of conduct.

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