# Thread over uneven (ragged) expressions with full functionality?

There are a number of questions on this site about "threading" including several relating to uneven (ragged) lists. However, none that I could find deal with the full functionality of Thread but instead things like MapThread, or the ragged transpose of Flatten[expr, {2}].

Thread operates:

• Inside held expressions without errant evaluation

• On arbitrary heads as specified with the second parameter

• By distributing singlets across all subexpressions

• On only the first n arguments (subexpressions) if given as third parameter

For example:

expr = Hold[qq[2 + 2, 1/0, 8/4], qq[1, 2, 3], Sqrt[2 + 2]];


qq[Hold[2 + 2, 1, Sqrt[2 + 2]], Hold[1/0, 2, Sqrt[2 + 2]], Hold[8/4, 3, Sqrt[2 + 2]]]

qq[Hold[2 + 2, qq[1, 2, 3], Sqrt[2 + 2]], Hold[1/0, qq[1, 2, 3], Sqrt[2 + 2]],
Hold[8/4, qq[1, 2, 3], Sqrt[2 + 2]]]


All of this breaks if we change qq[1, 2, 3] to qq[1, 2].

What is the most efficient way to extend Thread to ragged subexpressions?

-

This is my take on the pad, thread normally, then remove padding approach.

fred[expr_, head_: List, seq_: All] :=
Module[{myhold, maxlength, dummy, paddedexpr},
SetAttributes[myhold, HoldAllComplete];
maxlength = Max@Cases[expr, head[args___] :> Length@Hold@args, {1}];
RuleCondition@PadRight[myhold@args, maxlength, dummy], {1}];

-
Much more polished :) I didn't know Pad.. worked on arbitrary heads. Sweet. – mfvonh Jun 9 '14 at 22:05
+1, I would have done something quite similar. I think the Replace level better be {1} in case the whole expression is wrapped in head. – Rojolalalalalalalalalalalalala Jun 11 '14 at 0:53
Also, there's the small issue of definitions that didn't match now matching with the padded dummy arguments. Perhaps keeping the myhold and some other one for the head of heads, and replacing them back after the threading? Not sure if I am thinking straight, and I don't have MMA to try stuff – Rojolalalalalalalalalalalalala Jun 11 '14 at 0:53
@Rojo, thanks - good points. – Simon Woods Jun 11 '14 at 8:34

// timidly raises hand

Maybe this approach?

ClearAll[Thread2];
DeleteCases[
With[
{max = Length /@ {expr} // Max},
Quiet[
Replace[
expr,
h_[c___] /; 1 < Length@{c} < max :>
RuleCondition[
h[c,
Sequence @@ ConstantArray[EatMe, max - Length@{c}]]],
{1}]]], etc],
EatMe, 3];

expr = Hold[qq[2 + 2, 1/0, 8/4], qq[1, 2, 3], Sqrt[2 + 2]];

qq[Hold[2 + 2, 1, Sqrt[2 + 2]], Hold[1/0, 2, Sqrt[2 + 2]], Hold[8/4, 3, Sqrt[2 + 2]]]

qq[Hold[2 + 2, qq[1, 2, 3], Sqrt[2 + 2]], Hold[1/0, qq[1, 2, 3], Sqrt[2 + 2]],  Hold[8/4, qq[1, 2, 3], Sqrt[2 + 2]]]

expr2 = Hold[qq[2 + 2, 1/0, 8/4], qq[1, 2], Sqrt[2 + 2]];

qq[Hold[2 + 2, 1, Sqrt[2 + 2]], Hold[1/0, 2, Sqrt[2 + 2]], Hold[8/4, Sqrt[2 + 2]]]

qq[Hold[2 + 2, qq[1, 2], Sqrt[2 + 2]], Hold[1/0, qq[1, 2], Sqrt[2 + 2]], Hold[8/4, qq[1, 2], Sqrt[2 + 2]]]

-
There is no need to be timid. Thanks for answering. I had my own ideas for implementing this but I wasn't feeling very imaginative so I wanted to see how others would do it. – Mr.Wizard Jun 9 '14 at 7:30
Thread2[{{1, 2, 3, 4, 5}, {6, 7, 8}}] gives a Thread::tdlen error. – Simon Woods Jun 9 '14 at 12:43

If I understand the question correctly, you are looking to use Thread on ragged subexpressions. I will give my solution on ragged list:

list = {{a, b}, {c, f, r, t}, {t, y, k}};
length = Length[#] & /@ list;
max = Max@length;
list2 = Join[#, ConstantArray[0, max - Length[#]]] & /@ list;
list3 = Thread[List @@ list2];
list4 = DeleteCases[list3, _ 0, \[Infinity]];
f @@@ list4

(*    {f[a, c, t], f[b, f, y], f[r, k], f[t]}*)

-
Is this intended to be only an illustration? Will this handle the additional parameters of Thread? I think you would also need to avoid accidentally deleting zeros that were present in the original expression. By the way, you don't need to write Length[#] & /@ list -- Length is already a function, so write: Length /@ list. :-) – Mr.Wizard Jun 9 '14 at 7:34
@Mr. Wizard, thank you for your input. regarding deleting zero, this can be changed to be any value that is not showing in the ragged list. – Algohi Jun 9 '14 at 15:29