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

Array to hash converstion

by gem555 (Acolyte)
on Jul 15, 2009 at 04:48 UTC ( #780153=perlquestion: print w/replies, xml ) Need Help??

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

for my $data_pair (@data_list) { print "$data_pair->{'key'},$data_pair->{'value'}\n"; }
The coresponding key and value is printed. How to change the array to hash.

Replies are listed 'Best First'.
Re: Array to hash converstion
by NetWallah (Canon) on Jul 15, 2009 at 05:02 UTC
    What you seem to have is an array-of-hash-refs (AKA AoH).

    If each hashref contains only a single key/value pair, you can do this:

    my %newhash; for my $href (@data_list){ $newhash{ $href->{key} } = $href->{value}; } ## If you want to print the new hash ... for my $k (sort keys %newhash){ print "$k => $newhash{$k}\n"; }
    *Untested* Update: You could also use map:
    my %newhash = map {{ $_->{key} } = >$_->{value} } @data_list;

         Potentia vobiscum ! (Si hoc legere scis nimium eruditionis habes)

      my %newhash = map {{ $_->{key} } = >$_->{value} } @data_list;
      >perl -wMstrict -MData::Dumper -le "my @d_pairs = ( { key => 'foo', value => 'bar' }, { key => 'fee', value => 'fie' }, ); my %hash = map { $_->{key} => $_->{value} } @d_pairs; print Dumper \%hash; " $VAR1 = { 'fee' => 'fie', 'foo' => 'bar' };
Re: Array to hash converstion
by ELISHEVA (Prior) on Jul 15, 2009 at 06:19 UTC
    my @data_list = ( { key => 'a', value => 1 } , { key => 'b', value => 2 } , { key => 'c', value => 3 } ); #this line does the conversion my %hData = map { $_->{key} => $_->{value} } @data_list; print "@{[%hData]}\n";

    For more information, please see map, perldsc, and perldata.

    Best, beth

Re: Array to hash converstion
by Marshall (Abbot) on Jul 15, 2009 at 05:21 UTC
    Converting @data_list to a hash is easy. See below code. Basically if you assign an array to a hash, Perl treats this as key, value pairs. my %hash = @data_list; is all that is needed.
    #!/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
      Your solution, while valid (++) in the "normal" case, will probably not work for the O.P.

      His array contains hashrefs, so assigning that to a hash will not be usable.

           Potentia vobiscum ! (Si hoc legere scis nimium eruditionis habes)

        Yes, I did engage in a bit of "mind-reading" here. I didn't see any example input data or any example output data. I wound up not assuming that this was working code and I took a guess as to intent based upon the context of the question.

        If the OP is comfortable with AOH and wants HOH, then 1)So what are the keys to this HOH supposed to be? I didn't see anything about that. 2)Also, if the OP really is comfortable working with AoH, then AoH to HoH isn't that big of a leap and I would have expected some kind of "this is my attempt" code.

        I try to helpful. But, in general the usefulness and quality of the responses depends a LOT on the clarity of the question.

Re: Array to hash converstion
by quester (Vicar) on Jul 15, 2009 at 05:01 UTC
      You want to use the each function.

      I'm not sure I understand how "each" will solve this problem. I don't think that you do either, given that you haven't shown an example.

      See (This was the second hit in a Google search for "perldoc print hash each".)

      That's nicely self-referential, isn't it? How do you expect someone to come up with a Google search term that includes the name of the function they're looking for?


      See the Copyright notice on my home node.

      Perl training courses

      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
        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" );

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://780153]
Approved by NetWallah
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (4)
As of 2020-07-02 06:22 GMT
Find Nodes?
    Voting Booth?

    No recent polls found