Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.
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?

share|improve this question
    
@andre, I'd suggest putting that as an answer –  Simon Woods May 18 '13 at 21:30
1  
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. –  gwr May 19 '13 at 13:07
add comment

2 Answers

up vote 10 down vote accepted

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[]

share|improve this answer
1  
Why not explain why your code works but his does not? –  David Carraher May 19 '13 at 1:50
    
@DavidCarraher Explanation added. Hope I have explained what should be explained. –  andre May 19 '13 at 9:13
1  
Nice explanation (+1) and you also used :> rather than -> –  cormullion May 19 '13 at 9:16
    
@cormullion small explanation about :> and -> added (at the end) –  andre May 19 '13 at 9:58
    
Excellent - thanks. –  cormullion May 19 '13 at 10:02
show 1 more comment

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.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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