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

Hi, I need help.

I have an array which is a function of a number and a word, like $a[1]{"blue"}. If it were two numbers, I could process it with

for $i (1..$n) { for $j (1..$n) { ...stuff about $a[$i][$j] } }
If it were one-dimensional, I could use
foreach (keys %a) { ...stuff about $a{$_} }
But if my outer loop is
for $i (1..$n) { }
what syntax do I use to do a foreach over the second argument with the first held constant at $i???

TIA; please also answer by email to phil.rennert@ioip.com

Edit by tye, add CODE and P tags

Replies are listed 'Best First'.
Re: Syntax for partly associative arrays
by Zaxo (Archbishop) on Sep 05, 2003 at 17:41 UTC

    If @a is an array of hashes, you can iterate with,

    for (@a) { for (keys %$_) { # ... } }
    since the array elements are all hash references.

    After Compline,
    Zaxo

      Just to add to what Zaxo said, you'll probably want to use an explicit aliasing variable in your 'for' loops instead of $_ for clarities sake. Something like this:
      foreach my $hash (@a) { foreach my $word (keys %$hash) { my $wordvalue = $hash->{$word}; # ... } }
      Notice that because $hash is a reference to a hash you access its elements via ->{}. In general if you are going to iterate through an array, you want to use 'foreach's aliasing ability to access the elements of the array directly instead of accessing the elements through their indexes.
Re: Syntax for partly associative arrays
by shenme (Priest) on Sep 05, 2003 at 17:48 UTC
    Wouchw! That question didn't display like you typed, huh?   I think you meant $a[1]{"blue"} and $a[$i][$j]?   Is that right?

    Anyway, if you had a list of words to use you would still use foreach like so:

    my @words = qw( red blue peony ); for my $i ( 1.. $n ) { foreach my $w ( @words ) { print " I see '$a[$i]{$w}'\n"; } }
      Thanks to you all. I think I have less knowledge than you're asuming. Yes, I meant what shenme said; I don't know how to make square brackets display (now I do - put them inside code tags). I tried what fletcher suggested, and it worked, but I still don't know how to refer to the first variable inside the second loop. When I run
      #!/usr/bin/perl $a[1]{"blue"}=1; $a[1]{"red"}=2; $a[2]{"blue"}=3; $a[2]{"red"}=4; foreach $hash (@a) { foreach $word (keys %$hash) { print $firstval." ".$word." ".$hash->{$word}."\n"; } } I'd like to see 1 blue 1 1 red 2 2 blue 3 2 red 4
      but I don't know how to set $firstval to see that. I understand the idea of arrays and references (is a hash an array of references?), but I know only by rote when to use @, $, and % for arrays (and %$ is new to me). So does this mean that anytime a multidimensional array is partly associative, I have to use foreach for all loops on it? I thought there was a way to use for $i (1..n) for the numerical variables and foreach for the others, but I don't remember it. Phil Rennert
        Looking again, I think shenme answered my question, -if- I have a list of all the words the second variable can be, which I can make if I need to. But it seems awkward, especially since the word lists for $i=1, $i=2, etc. aren't identical. I can union the lists and put in a does-not-exist test; but it seems kludgey: is there a cleaner way?