Iterating over all elements in a 3D array

Discussion in 'Perl Misc' started by it_says_BALLS_on_your forehead, Mar 27, 2007.

  1. On Mar 27, 9:47 am, nikolas pontikos <> wrote:
    > Is there cleaner way of writing this:
    >
    > foreach $send (0...$#sr) {
    > foreach $recv (0...$#{$sr[$send]}) {
    > foreach $round (0...$#{$sr[$send][$recv]}) { print
    > "$sr[$send][$recv][$round]:\n";
    > }
    > }
    >
    >
    >
    > }


    yes. you needn't use an integer iterator. it's actually more efficient
    (and cleaner) to iterate over the array elements themselves.

    for my $lev1 ( @sr ) {
    for my $lev2 ( @{$lev1} ) {
    for my $lev3 ( @{$lev2} ) {
    print "$lev3\n";
    }
    }
    }

    ....you can also probably use maps or something more esoteric if you're
    more concerned with brevity and less concerned with readability. also,
    i'm not sure if it's more efficient to dereference the arrayref
    outside the nested loops or not. if i weren't so lazy i'd benchmark...
     
    it_says_BALLS_on_your forehead, Mar 27, 2007
    #1
    1. Advertising

  2. On Mar 27, 9:55 am, nikolas pontikos <> wrote:
    > nikolas pontikos wrote:
    > > Is there cleaner way of writing this:

    >
    > > foreach $send (0...$#sr) {
    > > foreach $recv (0...$#{$sr[$send]}) {
    > > foreach $round (0...$#{$sr[$send][$recv]})
    > > { print "$sr[$send][$recv][$round]:\n";
    > > }
    > > }
    > > }

    >
    > Actually sorry what I mean is a more generic way of doing this one which
    > would work with an N dimensional array.


    yes. you can write a recursive function, and even imbue it with
    intelligence enough to handle nested hashrefs as well as arrayrefs via
    the ref function.
     
    it_says_BALLS_on_your forehead, Mar 27, 2007
    #2
    1. Advertising

  3. it_says_BALLS_on_your forehead

    -berlin.de Guest

    nikolas pontikos <> wrote in comp.lang.perl.misc:
    > nikolas pontikos wrote:
    > > Is there cleaner way of writing this:
    > >
    > > foreach $send (0...$#sr) {
    > > foreach $recv (0...$#{$sr[$send]}) {
    > > foreach $round (0...$#{$sr[$send][$recv]})
    > > { print "$sr[$send][$recv][$round]:\n";
    > > }
    > > }
    > > }

    >
    > Actually sorry what I mean is a more generic way of doing this one which
    > would work with an N dimensional array.


    Sure.

    sub flatten { map ref() ? flatten( @$_) : $_, @_ }

    With that you can

    print "$_\n" for flatten(
    [ 1, 2, 3],
    [ 4, 5, 6],
    [ 7, 8, 9],
    );

    The arrays can be arbitrarily nested:

    print "$_\n" for flatten(
    [ 1, [ 2, 3, 4], [ 4, [ 5, 6], [[[[ 7]]]] ] ], 8, 9,
    );

    Anno
     
    -berlin.de, Mar 27, 2007
    #3
  4. Is there cleaner way of writing this:

    foreach $send (0...$#sr) {
    foreach $recv (0...$#{$sr[$send]}) {
    foreach $round (0...$#{$sr[$send][$recv]}) { print
    "$sr[$send][$recv][$round]:\n";
    }
    }
    }
     
    nikolas pontikos, Mar 27, 2007
    #4
  5. nikolas pontikos wrote:
    > Is there cleaner way of writing this:
    >
    > foreach $send (0...$#sr) {
    > foreach $recv (0...$#{$sr[$send]}) {
    > foreach $round (0...$#{$sr[$send][$recv]})
    > { print "$sr[$send][$recv][$round]:\n";
    > }
    > }
    > }


    Actually sorry what I mean is a more generic way of doing this one which
    would work with an N dimensional array.
     
    nikolas pontikos, Mar 27, 2007
    #5
  6. Michele Dondi wrote:
    > On Tue, 27 Mar 2007 14:47:54 +0100, nikolas pontikos
    > <> wrote:
    >
    >> Is there cleaner way of writing this:
    >>
    >> foreach $send (0...$#sr) {
    >> foreach $recv (0...$#{$sr[$send]}) {
    >> foreach $round (0...$#{$sr[$send][$recv]}) { print
    >> "$sr[$send][$recv][$round]:\n";
    >> }
    >> }
    >> }

    >
    > local $\=":\n";
    > for (@sr) {
    > for(@$_) {
    > for (@$_) {
    > print;
    > }
    > }
    > }
    >
    >
    > Michele


    So $\ is a perl variable that's appended to every string which gets
    printed out? That's pretty cool I didn't know that.

    Thanks,
    --
    Nikolas.
     
    nikolas pontikos, Mar 27, 2007
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Travis L Spencer
    Replies:
    3
    Views:
    371
    Travis L Spencer
    Jan 21, 2005
  2. Gerald Aichholzer
    Replies:
    2
    Views:
    2,560
    Gerald Aichholzer
    Jun 27, 2006
  3. Hicham Mouline
    Replies:
    1
    Views:
    407
    Kai-Uwe Bux
    Apr 11, 2010
  4. Ulrich Eckhardt
    Replies:
    6
    Views:
    359
    Bryan
    May 12, 2010
  5. Replies:
    4
    Views:
    195
Loading...

Share This Page