Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

Re^2: Array to hash converstion

by gem555 (Acolyte)
on Jul 15, 2009 at 05:14 UTC ( #780159=note: print w/replies, xml ) Need Help??


in reply to Re: Array to hash converstion
in thread Array to hash converstion

The above code prints only one pair of values.
for my $data_pair (@data_list) { print "$data_pair->{'key'},$data_pair->{'value'}\n"; } correct,AAA correction,BBB date,20090303 date,20090308
These values and keys should be converted to hash map

Replies are listed 'Best First'.
Re^3: Array to hash converstion
by spazm (Monk) on Jul 15, 2009 at 06:23 UTC
    I believe this is your question:
    "I have an array (@data_list) containing hash references. Each hash reference contains two keys, 'key' and 'value'. I want to turn this into one hash containing 'key'=>'value' pairs. How can I do this?"

    My solutions below assume that you have unique key values, or are un-interested in collisions. In the case of a collision, the last reference to the key wins.

    Here is a fully verbose version:

    my %final_hash; foreach my $data_pair ( @data_list) { $key = $data_pair->{ key }; $value = $data_pair->{value}; $final_hash{ $key } = $value; } use Data::Dumper; print Dumper \%final_hash;

    A shorter version:

    my %final_hash = map { $_->{key} => $_->{value} } @data_list; #verify the output use Data::Dumper; print Dumper \%final_hash;
    And how do we know they work? We test them.

    Full version with tests:

    #!/usr/bin/perl -w use strict; use Data::Dumper; use Test::More tests => 2; my @data_list = ( { key => 'correct', value => 'AAA' }, { key => 'correction', value => 'BBB' }, { key => 'date', value => '20090303' }, { key => 'date', value => '20090308' }, ); my $expected = { correct => 'AAA', correction => 'BBB', date => '20090303', date => '20090308', }; my %final_hash_long; foreach my $data_pair (@data_list) { my $key = $data_pair->{key}; my $value = $data_pair->{value}; $final_hash_long{$key} = $value; } my %final_hash_short = map { $_->{key} => $_->{value} } @data_list; is_deeply( \%final_hash_long, $expected, "long version works" ); is_deeply( \%final_hash_short, $expected, "short version works" );
      #!/usr/bin/perl -w use strict; my @value_pairs = qw (one abc two xyz); my %hash = @value_pairs; foreach my $key (keys %hash) { print "key $key is $hash{$key}\n"; } __END__ prints: key one is abc key two is xyz key one is def
      If two keys are same then, output is
      key one is abc key two is xyz
      so for the key one value is def is not printed here. The expected output is
      key one is abc key two is xyz key one is def
      Please tell me how can I get the output like this
        The issue you've run into here is that each hash key can only be associated with a single value, so the second assignment to $hash{one} overwrites its previous value. Or, as spazm put it in the comment you were replying to,
        My solutions below assume that you have unique key values, or are un-interested in collisions. In the case of a collision, the last reference to the key wins.
        However, the single value held by the hash doesn't have to be a simple scalar. If you use an array reference there (giving you a "hash of arrays" or "HoA"), then the code will be a little more complex, but you'll be able to store as many values as you like with each key:
        #!/usr/bin/perl use strict; use warnings; my @value_pairs = qw( one abc two xyz one def ); my %hash; while (@value_pairs) { my $key = shift @value_pairs; my $value = shift @value_pairs; push @{$hash{$key}}, $value; } for my $key (keys %hash) { print "key $key has values: ", join(', ', @{$hash{$key}}), "\n"; } __END__ key one has values: abc, def key two has values: xyz
      #!/usr/bin/perl -w use strict; use warnings; my @data_list = ( {key => 'correct', value => 'Article_text1'}, {key => 'correct', value => 'Article_text2'}, {key => 'date', value => '2009-01-01'}, {key => 'date', value => '2009-01-02'} ); my @correct; my @date; for my $data_pair (@data_list) { print "Value:$data_pair->{value}:Key:$data_pair->{key}\n"; if($data_pair->{key} eq 'correct'){ @correct = $data_pair->{value}; } if($data_pair->{key} eq 'date'){ @date = $data_pair->{value}; } } print "The array is @correct\n"; print "The array is @date\n";
      The array stores only the last value. How to store all the values into array

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://780159]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others rifling through the Monastery: (3)
As of 2020-07-05 21:10 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?