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

Hi,

I'm pretty new to perl, so sorry for the stupid question.

I want to do a "mass initialization" of a hash. I will have several keys with the same value :

${a}="toto" ... ${g}="toto" ${h}="titi" ...

and so on.

Is there a way to initialize multiple keys with the same value on one line ? for example smtg like:

${a,b,c,f,t,u}='toto'; ${b,g,k,p}='titi';

I can't find an easy way to do this.

Thank you all. /David

Code tags and other markup added by GrandFather

Replies are listed 'Best First'.
Re: Hash multiple initialization
by ikegami (Patriarch) on Oct 08, 2008 at 11:00 UTC

    New hash:

    my %hash = ( ( map { $_=>'toto' } qw( a b c f t u ) ), ( map { $_=>'titi' } qw( b g k p ) ), );

    Existing hash:

    $hash{$_} = 'toto' for qw( a b c f t u ); $hash{$_} = 'titi' for qw( b g k p );

    You have "b" twice, which means one (the earlier one) will get erased.

      Might this be a case in which prototyping is actually useful as a syntactic sweetener?

      sub mass_init (\%\@$); my @init_to_toto = qw{ a b c f t u }; my %hash = ( y => 'pre', z => 'pre', ); mass_init(%hash, @init_to_toto, 'toto'); mass_init(%hash, @{[ qw(b g k p) ]}, 'TITI'); use Data::Dumper; print Dumper \%hash; sub mass_init (\%\@$) { my ($hashref, $arrayref, $string) = @_; # $hashref->{$_} = $string for @$arrayref; @{ %$hashref }{ @$arrayref } = ($string) x @$arrayref; }
      Output:
      $VAR1 = { 'a' => 'toto', 'y' => 'pre', 'p' => 'TITI', 'c' => 'toto', 'u' => 'toto', 'k' => 'TITI', 'g' => 'TITI', 'b' => 'TITI', 'z' => 'pre', 'f' => 'toto', 't' => 'toto' };
        I don't see the point of the prototype. It actually makes your example caller bigger!
        my @init_to_toto = qw{ a b c f t u }; my %hash = ( y => 'pre', z => 'pre', ); mass_init(\%hash, \@init_to_toto, 'toto'); mass_init(\%hash, [qw( b g k p )], 'TITI'); use Data::Dumper; print Dumper \%hash; sub mass_init { my ($hashref, $arrayref, $string) = @_; # $hashref->{$_} = $string for @$arrayref; @{ %$hashref }{ @$arrayref } = ($string) x @$arrayref; }
Re: Hash multiple initialization
by JavaFan (Canon) on Oct 08, 2008 at 10:56 UTC
    I'd write that as:
    $hash{$_} = "toto" for qw [a b c d e f g];
    or as
    @hash{qw [a b c d e f g]} = ('toto') x 7;
Re: Hash multiple initialization
by BrowserUk (Patriarch) on Oct 08, 2008 at 11:06 UTC
      Wow! It is not often that BrowserUK makes a typo (his code sets just the first key). I think he meant:
      my %hash; @hash{qw[ a b c f t u] } = ('toto') x 6; @hash{qw[ b g k p ]} = ('titi') x 4;
      My personal favorite is:
      my %hash; my @array = qw[ a b c f t u]; @hash{@array } = ('toto') x @array;
      Update:Following a request from blazar: the typos made by BroswerUK were that the parentheses were omitted from the lhs of the x operator in both cases, and the final line was terminated with a comma instead of a semi-colon. It was probably the keyboard at fault - I have one just like it.

      Anyway, I prefer my solution ("My personal favorite") because there is nothing to change when the array changes size.