3
$\begingroup$
m = RandomInteger[{-5, 5}, {10, 10}];
m /. {x__, y_ /; y > 0} -> Style[{x, y}, Red]
% // TableForm

When m without style , TableForm or Grid works well on it. But when I set a style, it doesn't work as I expected. How can I fix the problem?

$\endgroup$
2
  • $\begingroup$ @andre, I'd suggest putting that as an answer $\endgroup$ Commented May 18, 2013 at 21:30
  • 1
    $\begingroup$ As a matter of taste I would rewrite the replacement rule as m /. l_List /; Last[l] > 0 :> ... . This formulation already hints at what is the problem with Style being applied to a list. $\endgroup$
    – gwr
    Commented May 19, 2013 at 13:07

2 Answers 2

10
$\begingroup$

Here is a solution :

m = RandomInteger[{-5, 5}, {10, 10}];
m /. {x__, y_ /; y > 0} :> (Style[#, Red] & /@ {x, y});
% // TableForm

Explanation about TableForm[]

TableForm[] accepts as argument only a List[] of List[].

m /. {x__, y_ /; y > 0} -> Style[{x, y}, Red] seems to be a List[] of List[] :

enter image description here

but in fact the red lines have a wrapper (Style[]) that indicates the color. Here is the InputForm of the same thing :

enter image description here

The solution is to wrap the color deeper in the expression with

m /. {x__, y_ /; y > 0} :> (Style[#, Red] & /@ {x, y}) :

It looks like nearly the same :

enter image description here

But this time we have a List[] of List[]. Here is the InputForm :

enter image description here

Small explanation about :> and not ->

My first attempt was to use :

m /. {x__, y_ /; y > 0} ->  (Style[#, Red] & /@ {x, y}  

with -> instead of :>

It didn't work.

The reason is the ordering of evaluation :

  • first Style[#, Red] & /@ {x, y} is evaluated.
    It becomes {Style[x, RGBColor[1, 0, 0]],Style[y, RGBColor[1, 0, 0]]}

  • then x is evaluated. With x=Sequence[1,2,3] for example, it gives

    Style[1, 2, 3, ... color informations ...]

    which is not a valid syntax for Style[]

$\endgroup$
5
  • 1
    $\begingroup$ Why not explain why your code works but his does not? $\endgroup$
    – DavidC
    Commented May 19, 2013 at 1:50
  • $\begingroup$ @DavidCarraher Explanation added. Hope I have explained what should be explained. $\endgroup$
    – andre314
    Commented May 19, 2013 at 9:13
  • 1
    $\begingroup$ Nice explanation (+1) and you also used :> rather than -> $\endgroup$
    – cormullion
    Commented May 19, 2013 at 9:16
  • $\begingroup$ @cormullion small explanation about :> and -> added (at the end) $\endgroup$
    – andre314
    Commented May 19, 2013 at 9:58
  • $\begingroup$ Excellent - thanks. $\endgroup$
    – cormullion
    Commented May 19, 2013 at 10:02
5
$\begingroup$

As excellently described by andre the problem is that style is applied to the row vectors rather than the array elements themselves, and TableForm is not written to handle this situation. For ease of use you may wish to write a variant of Style that automatically threads over lists:

style[args__] := Thread[Style[args], List, 1]

Now:

m = RandomInteger[{-5, 5}, {10, 10}];
m /. a : {__, _?Positive} :> style[a, Red]
% // TableForm

Note the simpler pattern form, and the use of :> to localize the pattern name a.

$\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.