P is for Practical PerlMonks

### Unfolding a nDeep structure

 on Jul 05, 2007 at 15:22 UTC Need Help??

FFRANK has asked for the wisdom of the Perl Monks concerning the following question:

Good morning monks!

1) Initialize a nDeep structure with zeros:

```#!/usr/bin/perl -w
use strict;

my \$deeepness = 5;

my @nDeep = ();

my \$dimention = 5;

for my \$deep0 (0..\$dimention-1) {
for my \$deep1 (0..\$dimention-1) {
for my \$deep2 (0..\$dimention-1) {
for my \$deep3 (0..\$dimention-1) {
for my \$deep4 (0..\$dimention-1) {
\$nDeep[\$deep0][\$deep1][\$deep2][\$deep3][\$deep4] = 0
+;
}
}
}
}
}
2) Do stuff with the structure, add data, etc.

3) Unfold the structure into a 2D array:

```for my \$deep0 (0..\$dimention-1) {
for my \$deep1 (0..\$dimention-1) {
for my \$deep2 (0..\$dimention-1) {
for my \$deep3 (0..\$dimention-1) {
for my \$deep4 (0..\$dimention-1) {
push @{\$AoA[\$deep0]}, \$nDeep[\$deep0][\$deep1][\$deep
+2][\$deep3][\$deep4];
}
}
}
}
}

for my \$row (0..\$#AoA) {
print "@{\$AoA[\$row]}\n";
}
I would be interested in this all happening only by specifying a deepness level (my \$deepness = 5 in this case).

Thanks for sharing your enlightening knowledge and your time, always very much appreciated.

Frank

Replies are listed 'Best First'.
Re: Unfolding a nDeep structure
by blokhead (Monsignor) on Jul 05, 2007 at 15:49 UTC
tye's modules to the rescue! Algorithm::Loops to handle the variable number of nested foreach-loops, and Data::Diver to handle the multi-dimensional array indexing.
```# (untested)
use Data::Diver qw[Dive DiveVal];
use Algorithm::Loops 'NestedLoops';

NestedLoops(
[ ( [0..\$dimension-1] ) x \$depth ],
sub {
my @indices = @_;
my \$val = Dive( \@multi_dimensional_array, @indices );

## do something with \$val. say, push it to an array
}
);
Update: Just noticed that you wanted to know how to initialize this big structure to zeroes. The Dive sub doesn't autovivify, but DiveVal does:
```## initialization

my @multi_dimensional_array;

NestedLoops(
[ ( [0..\$dimension-1] ) x \$depth ],
sub {
DiveVal( \@multi_dimensional_array, @_ ) = 0;
}
);

Thank you blockhead, I've been playing a bit with Dive. This would be part of a script were data is fed to @MDAsomeIndex in the form +1. I do not not have it behaving this way:
```#!/usr/bin/perl -w
use strict;
use Data::Diver qw[Dive DiveVal];
use Algorithm::Loops 'NestedLoops';

my @MDA;
my \$dimension = 3;
my \$depth = 2;

NestedLoops(
[ ( [0..\$dimension-1] ) x \$depth ],
sub {
DiveVal( \@MDA, @_ ) = 0;
}
);

\$MDA[0][0] += 1;

my @AoA;
for my \$level (0..\$dimension-1) {
NestedLoops(
[ ( [0..\$dimension-1] ) x (\$depth-1) ],
sub {
my @indices = @_;
my \$val = Dive( \@MDA, @indices );
push @{\$AoA[\$level]}, @\$val;
}
);}

for my \$row (0..\$#AoA) {
print "@{\$AoA[\$row]}\n";
}
Prints:
1 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0

Updated: Expected:
1 0 0
0 0 0
0 0 0

???

If I understand right (from looking at your example code in the OP), you want a structure that looks like this:
```@AoA = (
[ \$MDA[0][0][0], \$MDA[0][0][1], ... , \$MDA[0][2][2] ],
[ \$MDA[1][0][0], \$MDA[1][0][1], ... , \$MDA[1][2][2] ],
[ \$MDA[2][0][0], \$MDA[2][0][1], ... , \$MDA[2][2][2] ],
);
In other words, \$AoA[x] contains all the elements of the form \$MDA[x][*][*], if you follow my notation.

I don't see how this corresponds with your "Expected" data, but one thing I noticed is that you should make the following change:

```#            my \$val = Dive( \@MDA, @indices );
#            push @{\$AoA[\$level]}, @\$val;
my \$val = Dive( \$MDA[\$level], @indices );
push @{\$AoA[\$level]}, \$val;
Because when dealing with \$AoA[\$level], you only care about things starting form \$MDA[\$level]. Also, then \$val will not be an arrayref like it was before.

There are many equivalent ways to write this, but another way is the following: Here you can replace the entire foreach loop with this:

```NestedLoops(
[ ( [0..\$dimension-1] ) x (\$depth-1) ],
sub {
my @indices = @_;
my \$val = Dive( \@MDA, @indices );
push @{ \$AoA[\$indices[0]] }, \$val;
}
);
To explain this, it takes everything of the form \$MDA[a][b][c] and pushes it onto the array at \$AoA[a].

Re: Unfolding a nDeep structure
by ForgotPasswordAgain (Priest) on Jul 05, 2007 at 15:43 UTC

Seems like a job for recursion. With that, and knowing that you can do \$ref = \$arr->[3]; \$ref->[2]; in place of \$arr->[3][2], I think you can manage it. :)

Create A New User
Node Status?
node history
Node Type: perlquestion [id://625059]
Approved by Corion
Front-paged by GrandFather
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others exploiting the Monastery: (7)
As of 2021-06-22 18:01 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
What does the "s" stand for in "perls"? (Whence perls)

Results (108 votes). Check out past polls.

Notices?