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
Re: 3d arrays
by deibyz (Hermit) on Apr 07, 2005 at 13:07 UTC
|
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. | [reply] [d/l] [select] |
Re: 3d arrays
by RazorbladeBidet (Friar) on Apr 07, 2005 at 13:13 UTC
|
| [reply] |
Re: 3d arrays
by zentara (Archbishop) on Apr 07, 2005 at 15:06 UTC
|
| [reply] |
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.
| [reply] [d/l] [select] |
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. :)
| [reply] |
|
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.
| [reply] [d/l] |
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.
| [reply] |
|
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. | [reply] [d/l] [select] |
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 | [reply] |
|
|