Mathematica Stack Exchange is a question and answer site for users of Wolfram Mathematica. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I love the shorthand /@. It is amazing for readability (and laziness when typing). However, right now I find that I need Map at level 2, i.e. Map[f, List[List[a,b],List[c,d]], {2}], a lot and I'd wish there was a similar shorthand notation available for a map at level 2. Is there? If not, can we make one?

share|improve this question
8  
Map[f] /@ {{1, 2}}? you can always define new function map2[f,l]. – Kuba 12 hours ago
    
@Kuba. That's the usefulness of operator forms that I've been waiting for. My answer is silly. – march 12 hours ago
2  
@march I disagree, your answer is not silly but the canonical approach to this problem. – Mr.Wizard 10 hours ago
    
@Mr.Wizard. After reading the Performance section of your post, I see what you mean. Kuba's answer seemed elegant, and I did not expect the possible performance issues. – march 10 hours ago
    
@march I'd say my example is interesting but I wouldn't use it either :) This syntax doesn't scale and is incosistent in having both Map and /@. – Kuba 10 hours ago

I'm not aware of a simple one, but perhaps you could make your own? The following is not great because it requires you to enter CenterDot as Esc+.+Esc, and you can't control the precedence, but depending on your use-case, it might be useful. In addition, you can use whatever built-in symbol with no built-in meaning you want:

CenterDot[f_, a_] := Map[f, a, {2}]

Then:

enter image description here

share|improve this answer

Rojo shows a way in Is it possible to define custom compound assignment operators like ⊕= similar to built-ins +=, *= etc?

MakeExpression[RowBox[{f_, SuperscriptBox["/@", n_], expr_}], StandardForm] := 
  MakeExpression @ RowBox[{"Map", "[", f, ",", expr, ",", "{", n, "}", "]"}]

Now:

enter image description here

To enter this select /@ and use Ctrl+6 to create a Superscript.

I actually used this (or code very like it) for a while but I got tired of having to translate to the long form for posting here so I stopped.

You could use a variation of you want to allow for full levelspec rather map at (only) level n.


Performance

Syntactically I like Kuba's suggestion of Map[f] /@ expr but I have personally rejected this as a general replacement for Map[f, expr, {2}], and I would like to illustrate why.

An aside: the only reason I am offering this critique is because I find this form desirable; I had the same reaction as march, just longer ago: "That's the usefulness of operator forms that I've been waiting for." I still hope that at least the performance aspect will be improved in future versions.

Unfortunately in the current implementation (or at least 10.1.0, but I don't think this has changed in v11) Operator Forms cannot themselves be compiled, therefore Map[f] /@ expr forces unpacking of expr. To make a contrived example where the Operator Form is at a stark disadvantage I shall use an array of many rows and few columns.

big = RandomReal[1, {500000, 3}];

Map[Sin] /@ big     // RepeatedTiming // First

Map[Sin, big, {2}]  // RepeatedTiming // First
1.16

0.0482
On["Packing"];
Map[Sin] /@ big;

Unpacking array with dimensions {500000,3} to level 1. >>

Unpacking array with dimensions {3}. >>

Unpacking array with dimensions {3}. >>

Unpacking array with dimensions {3}. >>

Further output of Developer`FromPackedArray::punpack1 will be suppressed during this calculation. >>

At risk of belaboring a point there is another limitation or at least difference regarding Map[f] /@ expr: evaluation.

Compare:

Map[f, Hold[{a}, b, c], {2}]

Map[f] /@ Hold[{a}, b, c]
Hold[{f[a]}, b, c]

Hold[Map[f][{a}], Map[f][b], Map[f][c]]

Clearly these operations are not equivalent.

share|improve this answer

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.