0

I want to add a hash to an array which is constructed from a previous hash value. Let us say, we have a hash:

( a=>1, b=>2, c=>3, d=>4)

I want to transform it to an array of hashes which would contain the following:

[
    ('key' => 'a', 'value' => 1),
    ('key' => 'b', 'value' => 2),
    ('key' => 'c', 'value' => 3),
    ('key' => 'd', 'value' => 4),
]

For doing this, I wrote the below snippet:

%hash = (a=>1,b=>2, c=>3, d=>4);
@arr = ();
foreach(keys %hash) {
    # Making a hash
    %temp = ('key' => $_, 'value' => $hash{$_});

    # Getting its reference
    $hashref = \%temp;

    # Push the reference of hash in the array
    push( @arr, $hashref);

    # Print it to know its value
    print $_.' '.$hash{$_}."\n";
}

foreach(@arr) {
    # Deref the hash
    %h = %{$_};

    # Print the element
    print 'elem: '.$h{'key'}."\n";

    # Print the reference
    print "Ref: ";
    print ref $_."\n";

    # Print the keys in hash
    print "keys in hash: ".keys %h;
    print "\n";
}

But the output contains only four entries of only one reference:

c 3
a 1
b 2
d 4
elem: d
Ref: keys in hash: 2
elem: d
Ref: keys in hash: 2
elem: d
Ref: keys in hash: 2
elem: d
Ref: keys in hash: 2

Why is it adding duplicates? Any suggestion to add the all the values ?

The code can be tried here: http://ideone.com/OIZiGZ

I have already looked at many answers and then arrived here when it did not work.

2
  • There are a few much shorter ways of writing that while( my($k,$v) = each %hash ){ push @arr, { key => $k, value => $v } or push @arr, { key => $_, value $hash{$_} } for keys %hash or for( keys %hash ){ push @arr, { key => $_, value $hash{$_} } } Commented May 15, 2014 at 15:58
  • You should always have use strict; and use warnings; at the top of your Perl files until you know exactly why it is recommended. If you had made it so that it works under use strict; you would have most likely fixed your code by doing exactly what ysth recommended. Commented May 15, 2014 at 16:05

1 Answer 1

1

You are adding a reference to the same %temp hash each time.

Change your code to say:

my %temp = ('key' => $_, 'value' => $hash{$_});

and each time through the loop %temp will be a different hash.

Sign up to request clarification or add additional context in comments.

2 Comments

So does adding 'my' defines it as a new reference ?
Yes, 'my' limits the scope to the local block (enclosing) block.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.