MapThread works fine and dandy with rectangular list structures:

MapThread[f, {{{a, b}, {c, d}}, {{1, 2}, {3, 4}}}, 2]


{{f[a, 1], f[b, 2]}, {f[c, 3], f[d, 4]}}

But with a ragged structure, it starts complaining:

MapThread[f, {{{a, b}, {c, d, e}}, {{1, 2}, {3, 4, 5}}}, 2]


MapThread::mptd: "Object {{a,b},{c,d,e}} at position {2, 1} in MapThread[f,{{{a,b},{c,d,e}},{{1,2},{3,4,5}}},2] has only 1 of required 2 dimensions."

whereas I'd like:

{{f[a, 1], f[b, 2]}, {f[c, 3], f[d, 4], f[e, 5]}}

I can't see any obvious way to achieve a pairing of the corresponding elements, but maybe you can?

-

Perhaps something like this, as a more general alternative? However, without tweaking it forget about level specification

Function[Null, f[##], Listable] @@ A

-
 The magic of Listable! I knew there must have been some nice way to do it. – wxffles May 28 '12 at 4:27 @wxffles I like it. If you actually want to give the arguments as separate lists like in your solution, you don't even need the Apply – Rojo May 28 '12 at 4:37 The dangling first argument is ugly, but the construction works nicely. +1, of course. – J. M.♦ May 28 '12 at 5:47 @J.M, no more dangling first argument – Rojo Jul 31 '12 at 13:47

Here's a way to do it by mapping MapThread:

MapThread[f, #] & /@ Transpose[{{{a, b}, {c, d, e}}, {{1, 2}, {3, 4, 5}}}]
(* {{f[a, 1], f[b, 2]}, {f[c, 3], f[d, 4], f[e, 5]}} *)

-
This works great if you are working at level 2. I was hoping for something more general. Next time I'll try asking! – wxffles May 28 '12 at 3:42
@wxffles please provide more examples if you want a more general solution. – Mr.Wizard May 28 '12 at 3:47

It's probably bad form to answer your own question, but I did manage to get something to work while I was waiting:

myMapThread[f_, list1_, list2_, level_] :=
Module[{s}, Function[s,
Reap[MapIndexed[Sow[f[#1, s[[Sequence @@ #2]]]] &, list1, {level}]][[1]]]
[list2]];


Usage:

myMapThread[f, {{a, b}, {c, d, e}}, {{1, 2}, {3, 4, 5}}, 2]


{{f[a, 1], f[b, 2]}, {f[c, 3], f[d, 4], f[e, 5]}}

It's quite ugly though.

-
It's not bad form, in fact it is actively encouraged. – rcollyer May 28 '12 at 3:51
MapThread[f, lst[[1 ;; 2, #]]] & /@ {1, 2}


gives

(*{{f[a, 1], f[b, 2]}, {f[c, 3], f[d, 4], f[e, 5]}}*)


If

lst2 = {{{a, b}, {c, d, e}}, {{1, 2}, {3, 4, 5}}, {{aa, bb}, {cc, dd, ee}}};
MapThread[f, lst2[[1 ;; 3, #]]] & /@ {1, 2}


gives

(*{{f[a, 1, aa], f[b, 2, bb]}, {f[c, 3, cc], f[d, 4, dd], f[e, 5, ee]}}*)

-