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?
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[]
:
but in fact the red lines have a wrapper (Style[]
) that indicates the color.
Here is the InputForm
of the same thing :
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 :
But this time we have a List[]
of List[]
. Here is the InputForm
:
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[]
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
.
m /. l_List /; Last[l] > 0 :> ...
. This formulation already hints at what is the problem withStyle
being applied to a list. $\endgroup$