0
$\begingroup$

I need to construct a table that has variable dimension and variable ranges (see for tables with variable dimensions and constant ranges, e.g., this question).

Suppose there is a list list and I'd like to build a table whose form is

Table[expr, {x1, 1, Length@list}, {x2, 1, Length@(list[[x1]])}, ..., {xn, 1, Length@list[[x1, x2, ..., xn-1]]}],

where n is an integer equal to or less than the depth of list.

What I already tried is

list={{{{{1, 2, 3}, {4, 5, 6}}}}}; (*an example*)
var = Table[Symbol["$x" <> ToString@i], {i, Depth@list-1}];
range = Table[
   If[j == 1,
    {var[[j]], Hold@Length[list]},
    {var[[j]], Hold@Length[Part[list, Sequence @@ var[[;; j - 1]]]]}
    ]
   , {j, Length@var}];

(*range=={{$x1, Hold[Length[list]]}, 
{$x2, Hold[Length[list[[Sequence @@ var[[1 ;; j - 1]]]]]]}, 
{$x3, Hold[Length[list[[Sequence @@ var[[1 ;; j - 1]]]]]]}, 
{$x4, Hold[Length[list[[Sequence @@ var[[1 ;; j - 1]]]]]]}, 
{$x5, Hold[Length[list[[Sequence @@ var[[1 ;; j - 1]]]]]]}}*)

and

Table[expr, Sequence@@range]

but since I did not release Hold, this does not work.

Please tell me how can I use ReleaseHold or Evaluate appropriately in this case.

EDIT Actually, I forgot that I can use Dimensions to specify each range. However, I leave this question because still I don't understand how can I use ReleaseHold.

$\endgroup$
1
  • 1
    $\begingroup$ Another suggestion: table expression with iterators of the form Table[operator, {i, 1, Length@ expression}] can often be advantageously replaced by operator /@ expression. Since mapping doesn't require explicit knowledge of the size of the expression, it's much easier to handle variable-length cases. $\endgroup$
    – MarcoB
    Dec 10, 2021 at 13:26

1 Answer 1

1
$\begingroup$

That is a bit tricky. You need to assemble the iteration specification first and then insert it into a Table command.

For an example we first create some data:

n = 3;
list = Array[RandomInteger[{1, 9}] &, {3, 4, 5}]

The we define a function that gives us the length to iterate over:

getLength[d : {_Integer ...}] := Length[list[[Sequence @@ d]]];

Then we define the variables we need:

vars = Table[Symbol["x" <> ToString[i]], {i, n}];

Next we can create the iteration specifications:

iter = Table[{vars[[i]], getLength[Range[i - 1]]}, {i, 2, n}];
PrependTo[iter, {x1, Length[list]}];

Finally we insert this into a Table (note, Table has the attribute HoldAll, what makes the Evaluate necessary):

Table[vars, Evaluate[Sequence @@ iter]]

enter image description here

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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