Once upon a time...

I wrote a piece of code that did not exactly do what I wanted. Consider the following:

use strict ; use warnings ; use Data::Dumper ; my %hash_origin = ( 'key1' => 1, 'key2' => 1, 'key3' => 1 ) ; my @keys = qw( key1 key1 key2 key2 key2 ) ; my %hash ; foreach ( @keys ) { my $key = $_ ; $hash{ $key } += $hash_origin{ $key } ; } print Dumper( \%hash ) ; __END__ $VAR1 = { 'key1' => 2, 'key2' => 3 };

What was missing was the key 'key3' in the result because the result had to match the original hash! So I went back into solitude and pondered the following solution:

my %hash2 ; my @keys_origin = keys %hash_origin ; @hash2{@keys_origin} = (0) x @keys_origin ; foreach ( @keys ) { my $key = $_ ; if ( exists $hash2{ $key } ) { $hash2{ $key } += $hash_origin{ $key } ; } } print Dumper( \%hash2 ) ; __END__ $VAR1 = { 'key3' => 0, 'key2' => 3, 'key1' => 2 };

Awesome! Was it not until last Thursday that I knew I had found the solution for these kind of things, but then this pesky little code had sprung from my hands:

my %hash3_origin = ( 'key1' => [1, 2], 'key2' => [3, 4], 'key3' => [5, + 6] ) ; my @keys3_0 = qw( key1 key1 key2 key2 key2 ) ; my @keys3_1 = qw( key2 key3 key3 key3 key3 ) ; my %hash3 ; my @keys3_origin = keys %hash3_origin ; @hash3{@keys3_origin} = ([0, 0]) x @keys3_origin ; foreach ( @keys3_0 ) { my $key = $_ ; $hash3{ $key }->[0] += $hash3_origin{ $key }->[0] ; } foreach ( @keys3_1 ) { my $key = $_ ; $hash3{ $key }->[1] += $hash3_origin{ $key }->[1] ; } print Dumper( \%hash3 ) ; __END__ $VAR1 = { 'key3' => [ 11, 28 ], 'key1' => $VAR1->{'key3'}, 'key2' => $VAR1->{'key3'} };

As yo can see in the result this is not what is intended. So I went back into solitude. (And I am not kidding, my gf was calling me the other day: Can you stop doing your Perl Monkey stuff!!!). But nevertheless, I found this (and here it comes) ugly solution by replacing this line:

@hash3{@keys3_origin} = ([0, 0]) x @keys3_origin ;

into:

@hash3{@keys3_origin} = map [($_) x 2], (0) x @keys3_origin ;

But but but... why can't I just:

@hash3{@keys3_origin} = ((0, 0)) x @keys3_origin ; or @hash3{@keys3_origin} = (@{[0, 0]}) x @keys3_origin ;

Because scalar says: There is no equivalent operator to force an expression to be interpolated in list context because in practice, this is never needed. If you really wanted to do so, however, you could use the construction @{[ (some expression) ]} , but usually a simple (some expression) suffices.

Never needed? Well, there is only one way to say this: I need that right here! I want x in list-list context! And it seems there is no way to do it!

Dear Monks: Is there any way to do this more beautifully? I just can't grasp the ugliness of the solution that I have found! I seek for a nice to read one line instruction similar to the one that I already found.


In reply to Best way to initialize hash x repetition array? by Veltro

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.