MapThread Not Mapping on Ragged Array
A quick note about the problem:
While I was trying to write a generalization to my Flatten+Apply
approach I faced a problem that I need to now the Depth[array]
. Which makes it problematic for e.g. test = {#, Sin@#} &@Range@Range@
because symbolic Sin[1]
adds to the depth even though you would not care.
So now you have uneven, with respect to depth, arrays. And ArrayDepth
won't help you as it can't deal with ragged arrays.
Maybe that's it, I don't know. Anyway
Specific solution:
test = {#, Sin@N@#} &@Range@Range@3
Apply[
foo,
Flatten[test, {{2}, {3}, {1}}],
{2}
]
{{foo[1, 1]}, {foo[1, 1], foo[2, 2]}, {foo[1, 1], foo[2, 2], foo[3, 3]}}
General(?) solution
I'm not 100% sure but this looks like a generalization:
test = {#, Sin@N@#} &@Range@Range@Range@3;
MapThreadRagged[f_, arr_List, lvl_Integer
]:= MapThreadRagged[f, arr, lvl, Depth[arr]]
MapThreadRagged[f_, arr_List, lvl_Integer, depth_Integer] := Module[{spec}
, spec = RotateRight[List /@ Range[depth - 1], lvl];
Apply[f, Flatten[arr, spec], {lvl}]
]
MapThreadRagged[foo, test, 3] // MatrixForm
MapThreadRagged[foo, test, 2] // MatrixForm
MapThreadRagged[foo, test, 1] // MatrixForm
and to workaround a problem mentioned in the first paragraph:
test = {#, Sin@#} &@Range@Range@Range@3;
you can provide the depth by yourself:
MapThreadRagged[foo, test, 3, 5] // MatrixForm
MapThreadRagged[foo, test, 2, 5] // MatrixForm
MapThreadRagged[foo, test, 1, 5] // MatrixForm
Two more workarounds:
lists = {Range@Range@3, Range@Range@3};
MapThread[f, #] & /@ Transpose[lists]
Thread[g[f, Transpose[lists]]] /. g -> MapThread
Why not just pad the list and create an extra definition for f
?
f[0, 0] = Nothing;
MapThread[f, {PadRight@Range@Range@3, PadRight@Range@Range@3}, 2]
(* {{f[1, 1]}, {f[1, 1], f[2, 2]}, {f[1, 1], f[2, 2], f[3, 3]}} *)
or in case f[0,0]
is required to do something then this:
f[Missing[], Missing[]] = Nothing;
MapThread[f, {PadRight[Range@Range@3, {3, 3}, Missing[]], PadRight[Range@Range@3, {3, 3}, Missing[]]}, 2]
(* {{f[1, 1]}, {f[1, 1], f[2, 2]}, {f[1, 1], f[2, 2], f[3, 3]}} *)