Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical

multiple local vars in a foreach loop

by shawnkielty (Initiate)
on Jan 31, 2013 at 08:36 UTC ( #1016252=perlquestion: print w/replies, xml ) Need Help??
shawnkielty has asked for the wisdom of the Perl Monks concerning the following question:

Hello ... i am pretty new to perl -- I have a array that is a series of key value pairs What I want to do is a foreach loop through the array -- something like this:
my %hash; foreach $key $value (@keys) { $hash($key) = $value; }
Is this possible? Or do i just not understand the syntax?

Replies are listed 'Best First'.
Re: multiple local vars in a foreach loop
by LanX (Chancellor) on Jan 31, 2013 at 08:40 UTC

    The simple answer

    my %hash=@keys;

    already does what you want. =)


    The long answer!

    Regarding your initial question: "unfortunately not"!

    Perl5 doesn't provide a built-in way to have multiple loop vars in foreach.

    There are several workarounds with while loops:

    • destructive with splice or multiple shifts

    • iterator with List::MoreUtils::natatime() or pairwise()

    • classic with c-stile for with two index-increments per iteration

    but these workarounds have been discussed so often in the monastery that I'd prefer to link them after finding them.


    In this case (ignoring the solution on top) I would do something with splice:

    DB<113> @array = (a =>1,b=>2) => ("a", 1, "b", 2) DB<114> while ( my ($key,$val) = splice(@array,0,2) ) { $hash{$key}=$val; } DB<115> \%hash => { a => 1, b => 2 } DB<116> \@array # emptied! => []

    You need to copy @array in case I wanna keep the initial elements after the loop.

    Older discussions

    googling the monastery for splice+natatime

    Cheers Rolf


    Originally I proposed this code

    while(@array) { $hash{shift @array} = shift @array; }

    But I was bitten by precedence, the code does it the wrong way around:

    DB<108> @array = ( a => 1, b => 2 ) => ("a", 1, "b", 2) DB<109> $hash{shift @array} =shift @array while @array DB<110> \%hash => { 1 => "a", 2 => "b" }
Re: multiple local vars in a foreach loop
by roboticus (Chancellor) on Jan 31, 2013 at 11:21 UTC


    Update: LanX is (of course) correct.

    Not with foreach, but you can do it using while and each:

    my %hash; while (my ($key, $value) = each %hash) { ... }


    When your only tool is a hammer, all problems look like your thumb.

      Right answer to wrong question! ;-)

      DB<156> while (my ($key, $value) = each @a) { print "$key, $value" } +;; Type of arg 1 to each must be hash (not array dereference) at (eval 13 +5)[] line 2, near "@a) "

      Cheers Rolf

        Depends on the version of Perl: each.
        لսႽ ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1016252]
Approved by Corion
[ww]: ++ all (phony labels re "gaming"
[1nickt]: ambrus perhaps you know where the keys are?
[ww]: OTOH, -- for ads suggesting that being good at games is somehow eq "greatness"
[ambrus]: 1nickg: obviously the gamers don't know. but anyway, I need the whole room backlit, because watching a monitor in a dark room (like many people do) is tiring for my eyes, even more so than doing it in a lit room.
[1nickt]: ambrus I agree. I suspect one's eyes are always trying to adjust across the boundary between very bright and very dark ... like a camera's autofocus struggling to choose the target.

How do I use this? | Other CB clients
Other Users?
Others surveying the Monastery: (18)
As of 2017-03-27 13:55 GMT
Find Nodes?
    Voting Booth?
    Should Pluto Get Its Planethood Back?

    Results (320 votes). Check out past polls.