Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Unfolding a nDeep structure

by FFRANK (Beadle)
on Jul 05, 2007 at 15:22 UTC ( #625059=perlquestion: print w/replies, xml ) 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; } );

    blokhead

      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].

        blokhead

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. :)

Log In?
Username:
Password:

What's my password?
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?