UnFlatten an array into a ragged matrix
Here is a version which is quite general, and based on Mr.Wizard's dynP function:
dynP[l_, p_] :=
MapThread[l[[# ;; #2]] &, {{0}~Join~Most@# + 1, #} &@Accumulate@p]
ClearAll[tdim];
tdim[{dims__Integer}] := Times[dims];
tdim[dims : {__List}] := Total@Map[tdim, dims];
ClearAll[pragged];
pragged[lst_, {}] := lst;
pragged[lst_, dims : {__Integer}] :=
Fold[Partition, lst, Most@Reverse@dims];
pragged[lst_, dims : {__List}] :=
MapThread[pragged, {dynP[lst, tdim /@ dims], dims}];
It may look similar to other answers, but the difference is that it can take more general specs. Example:
pragged[Range[20], {{{2, 3}, {2, 4}}, {2, 3}}]
(*
{
{{{1, 2, 3}, {4, 5, 6}}, {{7, 8, 9, 10}, {11, 12, 13, 14}}},
{{15,16, 17}, {18, 19, 20}}
}
*)
In general, the specs to pragged
will form a tree.
Here is a semi-imperative way:
result = Module[{i = 1}, Array[myflatarray[[i++]]&, #]& /@ mydimensions];
result === original
(* True *)
It uses Array
to build up each of the original submatrices, taking successive elements from the flat array.
MapThread[
Partition,
{Internal`PartitionRagged[myflatarray, Times @@@ mydimensions], mydimensions[[All, 2]]}
]
Internal`PartitionRagged
is undocumented. An example of how it works is:
Internal`PartitionRagged[{1,2,3,4,5},{3,2}]
(* Out: {{1,2,3},{4,5}} *)