Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

How cand I find each dimension x,y,z of a 3D arrays

by Arnaud (Initiate)
on Apr 09, 2001 at 13:54 UTC ( #70962=perlquestion: print w/replies, xml ) Need Help??

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

I try to find the size of each dimension (sizeX, sizeY, sizeZ) of my 3D array
which looks like the following:
$myArray["service1"][0][0]="100"; $myArray["service1"][0][1]="101"; $myArray["service2"][1][2]="212"; ...

Originally posted as a Categorized Question.

Replies are listed 'Best First'.
Re: How cand I find each dimension x,y,z of a 3D arrays
by tilly (Archbishop) on Apr 09, 2001 at 19:37 UTC
    An important point that nobody has pointed out:
    $myArray["service1"]
    will not do what you want. If you want to look up things by name, you will need a hash.

    For learning and playing around with data structures like this I recommend using Data::Dumper so you can easily see what Perl really has done (which may be very different from what you think it is doing).

Re: How cand I find each dimension x,y,z of a 3D arrays
by jeroenes (Priest) on Apr 09, 2001 at 14:58 UTC
    This code will recurse through the elements, and print the number of array-elements for each array in your structure. Will not decent hashes but can be hacked a bit to do that as well.
    use strict; my @a = ([([0..3] ) x 4]) x 3; arraylength( \@a ); sub arraylength{ my $a = shift; my $dim = 0; _length( $a, $dim ); } sub _length{ my $a = shift; my $dim = shift; if ( ref( $a ) =~ /ARRAY/ ){ print "\t" x $dim; print "dim $dim -> ".(scalar @$a)." elements"; print "\n\n" if $dim == 0; print "\n" if $dim == 1; _length( $_, $dim + 1) for ( @$a ); print "\n"; } }
    This example prints:
    dim 0 -> 3 elements dim 1 -> 4 elements dim 2 -> 4 elements dim 2 -> 4 elements dim 2 -> 4 elements dim 2 -> 4 elements dim 1 -> 4 elements dim 2 -> 4 elements dim 2 -> 4 elements dim 2 -> 4 elements dim 2 -> 4 elements dim 1 -> 4 elements dim 2 -> 4 elements dim 2 -> 4 elements dim 2 -> 4 elements dim 2 -> 4 elements
      Very cool. But can I make one small suggestion? Use this function for length:
      sub _length{ my $a = shift; my $dim = shift; if ( ref( $a ) =~ /ARRAY/ ){ print "\t" x $dim; print "dim $dim -> ".(scalar @$a)." elements"; print "\n" if $dim == 0; print "\n"; _length( $_, $dim + 1) for ( @$a ); } }
      It's exactly the same logic, but prints newlines a little differently. Otherwise, you don't get the nice formatting for arrays with four or more dimensions.
Re: How cand I find each dimension x,y,z of a 3D arrays
by davorg (Chancellor) on Apr 09, 2001 at 14:18 UTC

    Arrays in Perl don't have fixed dimensions. If you have a 2D array (actually an array of references to arrays), it is quite possible that each second level array has a different number of elements.

    Here is some code to print the number of elements in each second level array in such a data structure. The concept is easily extendable to three dimensions.

    my @AoA = (['the', 'first', 'array'], ['another', 'array'], ['this', 'is', 'the', 'last', 'one']); foreach (@AoA) { print scalar @$_, " elements\n"; }

    This prints out:

    3 elements 2 elements 5 elements

    Originally posted as a Categorized Answer.

Re: How cand I find each dimension x,y,z of a 3D arrays
by DrHyde (Prior) on Jun 19, 2003 at 09:33 UTC
    In a perl array of arrays, just like in C, the data structure does not have to be rectangular (or cuboidal, or ...). For example, you can have an array like so:
    @foo = ( [0, 1, 2, 3, 4, 5], [0, 1, 2], [0, [ 0, 1, 2, 3 ]] );
    There, @foo contains three references to arrays, all of which are of different lengths. One of them contains a reference to another array as well as an ordinary scalar. The following code will tell you the largest number of elements in each dimension. Dimensions are numbered starting at zero (I assume $[ has not been altered):
    my @foo = ( [0, 1, 2, 3, 4, 5], [0, 1, 2], [0, [ 0, 1, 2, 3 ]] ); my @maxlength = (); figger_out_depth(0, @foo); print "max dimensions:\n"; print " $_: $maxlength[$_]\n" foreach (0..$#maxlength); sub figger_out_depth { my $depth = shift; $maxlength[$depth] = 0 unless(defined($maxlength[$depth])); foreach my $element (@_) { figger_out_depth($depth + 1, @{$element}) if(ref($element) eq +'ARRAY'); } $maxlength[$depth] = $#_ + 1 if($#_ >= '0'.$maxlength[$depth]); }
Re: How cand I find each dimension x,y,z of a 3D arrays
by Anonymous Monk on Sep 28, 2004 at 19:53 UTC

    I made this subroutine for work so I guess it's more specific than the other two answers, but I find that this one can be modified and understood far easier than the others:

    #this prints 0 print getSecondArraySize("la", %test)."\n"; # put stuff in $test{"la"}[0] = "1"; $test{"la"}[1] = "2"; $test{"la"}[2] = "3"; #this prints 3 print getSecondArraySize("la", %test)."\n";

    And here's the code:

    ########################################################## # subroutine getSecondArraySize # Parameter: An associative array containing scalar # array and the name of a key # Returns the total amount of element(s) in the scalar # array within the associative array at the key location # index ########################################################## sub getSecondArraySize { # receives the argument my ($index, %array_to_count) = @_; # create the variable and get the number my $count=0; # determine the total amount of elements in the array while (defined($array_to_count{$index}[$count])) { $count++; } return $count; }

      Just curious, but couldn't this be accomplished with

      $#{$array_to_count{$index}}+1
      as well, instead of using the while loop?

      That way the code would be

      sub getSecondArraySize { # receives the argument my ($index, %array_to_count) = @_; # return the count return $#{$array_to_count{$index}}+1; }
      Thoughts,
      -v
      "Perl. There is no substitute."

      #this prints 3 print getSecondArraySize("la", %test)."\n"; #this prints 3 print scalar @{$test{la}}, "\n";

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://70962]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others avoiding work at the Monastery: (4)
As of 2022-11-29 02:31 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Notices?