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

I have the following hash in my code
my %coords = ("061"=>[220,140],"062"=>[34,89],"074"=>[34,89]);
To access the x coord of "061" i use $coords{"061"}[0]
and for y I use
$coords{"061"}[1]
But, I want to use this hash in a for loop, therefore I want to access the coords of "061", then "062", and finally "074". How do I do this?

Replies are listed 'Best First'.
Re: using hash values inside an array.
by Rich36 (Chaplain) on May 03, 2002 at 21:14 UTC

    Easy to do in a foreach loop - loop through the keys of the hash, then deference the array reference (the value of the hash), then loop through the array.

    my %coords = ("061"=>[220,140],"062"=>[34,89],"074"=>[34,89]); foreach my $coord (sort keys %coords) { foreach(@{ $coords{$coord} }) { print qq(Key: $coord Coordinate: $_\n) if $_; } } __DATA__ Key: 061 Coordinate: 220 Key: 061 Coordinate: 140 Key: 062 Coordinate: 34 Key: 062 Coordinate: 89 Key: 074 Coordinate: 34 Key: 074 Coordinate: 89

    Rich36
    There's more than one way to screw it up...

Re: using hash values inside an array.
by thelenm (Vicar) on May 03, 2002 at 21:16 UTC
    This is well explained in perlref and perldsc, which talk about manipulating nested data structures. If you read through them, you will find them very useful, and full of examples.

    As a short example of how to loop over a hash of lists, here is a crude way to print out your data structure:

    for my $key (keys %coords) { print "$key =>\n"; for my $x_coord (@{$coords{$key}}) { print " $x_coord\n"; } }
Re: using hash values inside an array.
by jsprat (Curate) on May 03, 2002 at 21:12 UTC
    Untested:

    for (qw(061 062 074)){ $coords{$_}[1]... }

    or

    for (keys %coords){ $coords{$_}[1]... }

Re: using hash values inside an array.
by Fastolfe (Vicar) on May 04, 2002 at 15:54 UTC
    While other posters mention the use of keys, I just want to point out that if all you're interested in is the values, you can use the values function to just pull those out:
    foreach my $value (values %coords) { printf("%d-%d\n", $value->[0], $value->[1]); }
    Also, be sure to remember that hash order is not guaranteed. If you need these things to be ordered based on the hash key, you'll need to use sort in conjunction with keys as in others' examples to accomplish this.
Re: using hash values inside an array.
by mephit (Scribe) on May 04, 2002 at 19:32 UTC
    You can always use map, too:
    my @xcoords = map { $coords{$_}[0] } (keys %coords
    Or just replace (keys %coords) with the list of whatever values you want. For example:
    my @xcoords = map { $coords{$_}[0] } qw(061 062);
    (The 'qw' is necessary, otherwise Perl will convert "062" into "62," which isn't What You Want.)

    Or, as someone else suggested, just use the values instead of the keys:

    my @xcoords = map { $_->[0] } (values %coords);
    HTH