Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

3d arrays

by Anonymous Monk
on Apr 07, 2005 at 12:52 UTC ( [id://445627]=perlquestion: print w/replies, xml ) Need Help??

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

Hi there
Ok. Imagine the following example. I have a 2D matrix, split into squares. Each square has its own set of co-ordinates. e.g square 1 will have the co-ordinates x = 1, y = 1, square 15 might have the co-ordinates x = 1, y = 15 and so on.
Now imagine each of these squares are populated by say .. beans. So, square 1 might be populated by 5 beans and square 15 might be populated by 65 beans.
What I am trying to do is something akin to a 3D array, storing the x,y co-ordinates and the number of beans, so I can print it later on in the program.
I'm fairly new to perl so not entirely sure how to go about this. From what I had read, perl doesnt necessarily have 3D arrays, but there is a way around this.
Anyway, any advice would be much appreciated.
Thanks in advance

Replies are listed 'Best First'.
Re: 3d arrays
by deibyz (Hermit) on Apr 07, 2005 at 13:07 UTC
    perlreftut
    perllol

    I think an AoA should be what you need. Something in the lines of:

    my $beans = [ [ 1 , 2 ], [2 , 3] ];

    Here, $beans->[0][0] would have 1 bean, $beans->[0][1] 2, etc...
    You don't need a "3rd dimension" for the array beacause you can have the number of beans as value.

    Hope it helps,
    deibyz

    Note: Code untested.

Re: 3d arrays
by RazorbladeBidet (Friar) on Apr 07, 2005 at 13:13 UTC
    You probably want to examine perlreftut, but here are some thoughts. I'm not sure just how familiar you are with Perl, so you might want to check perldata just to see the datatypes (specifically, hashes and arrays). You may want to read those before proceeding with this post

    That being said, you could represent this many ways.

    1. A 3D array, as you say, which would actually be an array of array references of array references. A possibility, but probably unnecessary, as your indices would be x,y,beans - and that would probably waste space (i.e. sparse)
    2. An array of hashrefs - this could contain something like an object. Each hashref could have the keys "x", "y" and "beans" and those values individually.
    3. Some combination of the two, e.g. an array of hasherefs of arrayrefs . Keys being "coordinates" (value of arrayref) and "beans" ( value being scalar)
    I'm sure there are many more ways to represent this, but just don't want you to get "stuck" into thinking of just arrays. Perl is much more fun than that :)
    --------------
    "But what of all those sweet words you spoke in private?"
    "Oh that's just what we call pillow talk, baby, that's all."
Re: 3d arrays
by zentara (Archbishop) on Apr 07, 2005 at 15:06 UTC
Re: 3d arrays
by Roy Johnson (Monsignor) on Apr 07, 2005 at 16:37 UTC
    Do you need to look things up by coordinates? Do you need to be able to walk through the grid in order? Do you need to be able to jump to a particular row?

    How you want to get your data back is important in determining how you should store it. A simple array of arrays might suit you:

    my @arr; while (my ($x, $y, $beans) = read_grid_cell) { push @arr, [$x, $y, $beans]; } # Or the equivalent map statement, if you like.
    You could certainly print the grid back out later. But if you want to get at certain cells (but not be able to walk through in order), you might need a multi-dimensional hash:
    my %hash; while (my ($x, $y, $beans) = read_grid_cell) { $hash{$x}{$y} = $beans; }
    If you need walkability as well as individual cell access, you would have to combine techniques:
    my @beans; my %grid; while (my ($x, $y, $beans) = read_grid_cell) { push @beans, [$x, $y, $beans]; $grid{$x}{$y} = $beans; } # Now you can walk through @beans, or you can lookup by $x and $y, # but don't change the beans in either spot, because they're not linke +d!

    Caution: Contents may have been coded under pressure.
Re: 3d arrays
by Anonymous Monk on Apr 07, 2005 at 17:48 UTC
    Thank you all again for your help thus far. I'm certainly beginning to understand a little more about perls more complicated data structures.
    What I think I actually need is a way of populating the hash/array ...
    The program in question is fed a text file on the command line. This text file has all the co-ordinates as follows:
    10.7 87.5
    34.8 90.0
    etc ...
    So, what I need to do is to first collect together the number of times say that there is a bean at co-ordinates x=10.7 and y=87.5 and then print them off like I mentioned before at the end
    10.7 87.5 5 for example
    Again, any advice much appreciated. :)
      So the input is unordered, each line indicates one bean at the location given, and you just want to tally them up and then print them out in grid order? Sounds like:
      my %beancounts; while (<>) { my ($x, $y) = split; ++$beancounts{$x}{$y}; } for my $x (sort {$a <=> $b} keys %beancounts) { for my $y (sort {$a <=> $b} keys %{$beancounts{$x}}) { print "$x $y $beancounts{$x}{$y}\n"; } }

      Caution: Contents may have been coded under pressure.
Re: 3d arrays
by Anonymous Monk on Apr 07, 2005 at 16:20 UTC
    Thank you for your help so far. It is much appreciated. I have to admit to still feeling rather confused though. What I want to print out is the exact co-ordinates as well as how many beans, and some of these co-ordinates wont be whole numbers ... for example
    101.67 80 5
    312.0 67.8 7
    and so on
    Perhaps arrays arent the best way of doing this, I dont know.
    Any thoughts much appreciated.
      If you need real coordinates, an Array wouldn't be enough. You can switch to a HoH (Hash of hashes), something in the lines of:

      my $HoH = { 101.67 => { 80 => 5 } , 312 => { 67.8 => 7 } };

      Then you can retrieve the values with $HoH->{312}{67.8}.

      Just be aware that hash keys are strings, so use sprintf if you get them from variables, or you're going to get strange results.

Re: 3d arrays
by Forsaken (Friar) on Apr 08, 2005 at 15:18 UTC
    an array of array would be by far the easiest solution with regards to actually retrieving data, however, the fact that the coordinates are fractional makes this rather complicated. if the fractions remain limited to 1 or 2 digits it'd still be workable to use ie an array whose values are then divided by 100.

    the other approach would be to simply run through the file, one line at a time, and to split() the line into $x, $y and $beans, after which you simply add it to a 1-dimensional hash using ie $beancounter{$x}{$y} = $beans;

    hope that helps a bit

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others surveying the Monastery: (3)
As of 2024-04-19 21:45 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found