5
$\begingroup$

How can I change the elements of a list, say on positions {{1, 4}, {3, 1}, {2, 3}, {4, 4}} in one go?

Take this list for example:

In:= (m = Array[RandomInteger[9] &, {4, 4}]) // TableForm

Out= 0  6   2   8
     3  8   8   0
     3  7   4   1
     4  8   2   4

This is how I want to the elements on the specified positions to change.

m[[1, 4]] = Style[m[[1, 4]], 14, Bold, Blue];

m // TableForm

Mathematica graphics

The result is that the 8 in the last element of the first row is now blue and bold (and bigger to stand out).

$\endgroup$
0

3 Answers 3

14
$\begingroup$

MapAt is probably the most direct:

MapAt[Style[#, Bold, Blue] &, m, {{1, 4}, {3, 1}, {2, 3}, {4, 4}}] // TableForm

Mathematica graphics

However this makes a copy of the table rather that modifying it in place. You could use m = MapAt[ . . . ] but this still uses additional memory.

Although it may not meet the requirement of "in one go" doing your Part assignment for each element is I believe the most efficient method:

(m[[##]] = Style[m[[##]], Bold, Blue]) & @@@
   {{1, 4}, {3, 1}, {2, 3}, {4, 4}};

m // TableForm

Mathematica graphics

J. M. remarks that this method would be better implemented using Scan. That is true if you are doing many replacements as the list built by using @@@ takes memory. With Scan it would look like this:

(m[[##]] = Style[m[[##]], Bold, Blue]) & @@ # & ~Scan~ 
   {{1, 4}, {3, 1}, {2, 3}, {4, 4}};
$\endgroup$
12
  • $\begingroup$ Thanks, I guess both approaches can be used in many situations. $\endgroup$
    – sjdh
    Commented Jun 30, 2012 at 9:03
  • $\begingroup$ How did you make the pictures of the matrix? $\endgroup$
    – sjdh
    Commented Jun 30, 2012 at 9:04
  • 4
    $\begingroup$ @sjd You can use Szabolcs's image uploader palette for this. See this link for more information and a download link. $\endgroup$
    – Heike
    Commented Jun 30, 2012 at 9:10
  • 1
    $\begingroup$ I'd have used Scan[] myself instead of Apply[] for the second method... $\endgroup$ Commented Jun 30, 2012 at 13:06
  • 1
    $\begingroup$ @paradox2 I understand now. I don't believe it can be done for the "pixel perfect Windows version" because that uses Copy As Bitmap which doesn't support transparency. For the "multiplatform" version (which can also be used on Windows) this should be simply a matter of inserting Background -> None into Rasterize[target, "Image"]; and ExportString[g, "PNG"];. However, you should contact Szabolcs to make the changes as I am not deeply familiar with his code. "Upload SE transparent" would be a useful button in my opinion. $\endgroup$
    – Mr.Wizard
    Commented Jul 2, 2012 at 14:20
2
$\begingroup$
m = {{0, 6, 2, 8}, {3, 8, 8, 0}, {3, 7, 4, 1}, {4, 8, 2, 4}};

positions = {{1, 4}, {3, 1}, {2, 3}, {4, 4}};

ReplaceAt

ReplaceAt (introduced in Version 13.1) is a close sibling of MapAt and ReplacePart:

ReplaceAt[x_ :> Style[x, Bold, Blue], positions] @ m // MatrixForm

enter image description here

MapIndexed + ReplaceAll

MapIndexed[
 ReplaceAll[{Alternatives @@ positions :> 
   Style[#, Blue, Bold], _ -> #}] @ #2 &, m, {2}] // MatrixForm

enter image description here

$\endgroup$
1
$\begingroup$

Using SubsetMap:

Clear["Global`*"];
SeedRandom[1];
(m = Array[RandomInteger[9] &, {4, 4}]);
locs = {{1, 4}, {3, 1}, {2, 3}, {4, 4}} 
{m, SubsetMap[Map[Style[#, Bold, Blue] &], m, locs]} // 
 Map[MatrixForm]

enter image description here

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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