Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw

Converting array of hash references to hash

by anirudh.agarwal (Novice)
on Apr 22, 2013 at 09:14 UTC ( #1029827=perlquestion: print w/replies, xml ) Need Help??
anirudh.agarwal has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks, I would like to convert a array of hash ref to hash and check a value in it. This is how it goes. The following code gets the array reference in $ams_hosts

my $ams_hosts = $request->get_config()->get_ams_hosts($domain);
The following code
print STDERR Dumper @{$ams_hosts};
prints this
$VAR1 = { 'domainId' => '1', 'deviceIp' => '', 'deviceType' => 3, 'deviceName' => 'AMS' }; $VAR2 = { 'domainId' => '1', 'deviceIp' => '', 'deviceType' => 3, 'deviceName' => 'ams_57' };
Now i would like to check if a scalar variable, say $ams_ip=, does not exist in the above hash assign undef to $ams_ip. I thought of assigning the array to hash with (key,value) as (deviceIp,<its correspponding ip address like> ) I tried the following snippet
my %ams_ips_hash = map {$_->{'deviceIp'}++} @{$ams_hosts}; $ams_ip = "" if !exists $ams_ips_hash{ $ams_ip};
but it doesnt work. Please let me know what I am doing wrong and what would make it right. As I am new to perl, I would be obliged to learn from perl monks like you. Your help is highly appreciated. Thanks in advance :) .

Replies are listed 'Best First'.
Re: Converting array of hash references to hash
by hdb (Monsignor) on Apr 22, 2013 at 09:30 UTC

    In map you need to return pairs to fill your hash:

    my %ams_ips_hash = map { $_->{'deviceIp'} => 1 } @{$ams_hosts};

      Personally I'd...

      my %ams_ips_hash = map { $_->{'deviceIp'} => $_ } @{$ams_hosts};
      package Cow { use Moo; has name => (is => 'lazy', default => sub { 'Mooington' }) } say Cow->new->name
        Thanks for your reply. This one stores (key,value) as (IP, entire hash). This is again not what I want.
      What actually happens in your case is, the value of deviceIp, say, changes to 172.16 . Is it because that perl is taking it as an integer?

        I do not understand. If I run:

        use strict; use warnings; use Data::Dumper; my $ams_hosts = [ { 'domainId' => '1', 'deviceIp' => '', 'deviceType' => 3, 'deviceName' => 'AMS' }, { 'domainId' => '1', 'deviceIp' => '', 'deviceType' => 3, 'deviceName' => 'ams_57' } ]; my %ams_ips_hash = map { $_->{'deviceIp'} => 1 } @{$ams_hosts}; print Dumper( \%ams_ips_hash );

        I get

        $VAR1 = { '' => 1, '' => 1 };

        Can you clarify what you mean please?

Re: Converting array of hash references to hash
by hdb (Monsignor) on Apr 22, 2013 at 09:40 UTC

    You can also answer your question w/o creating a hash:

    $ams_ip = "" unless grep { $ams_ip eq $_->{'deviceIp'} } @{$ams_hosts} +;

    but this would be computationally more expensive if you need to perform this query many times.

      This one definitely works. Thanks. This query is executed only once per request in my case. I hope in that case even if  @{$ams_hosts} has a large data, it wont be expensive. :) Thanks again
      I verified that use of any instead of grep increases the performance.
        > I verified that use of any instead of grep increases the performance.

        sure, but List::MoreUtils is not core...

        lanx@nc10-ubuntu:~$ corelist List::MoreUtils List::MoreUtils was not in CORE (or so I think)

        ... thats why it's easier to show working code w/o dependencies.

        With List::MoreUtils present any is for sure the better choice!

        Cheers Rolf

        ( addicted to the Perl Programming Language)

      When I check the above statement using Perl Critic, it finds the following violation. "grep" used in boolean context. I see this strange.
        I then found that grep would search for the rest of the array even if a match is found in the first record itself. I believe any should be used. Let me try the following $ams_ip = "" unless any { $ams_ip eq $_->{'deviceIp'} } @{$ams_hosts}; Please let me know if I am wrong. Thanks :)
Re: Converting array of hash references to hash
by Anonymous Monk on Apr 22, 2013 at 09:16 UTC
    Why do you have ++ in  $_->{'deviceIp'}++ ?
      I feel it is a similar way of giving $_->{'deviceIp'}=>1. But I am not sure.
Re: Converting array of hash references to hash
by rpnoble419 (Pilgrim) on Apr 22, 2013 at 16:54 UTC

    Why do the conversion in the first place. If the data is consistent, write your program to loop through the array. It might be helpful to look at this tread Map Vs Foreach. I'm not against using map, but if the list is very long you may run into other problems.


    you may want to check out this module to see if does what you want Hash-MostUtils

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1029827]
Approved by Ratazong
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (7)
As of 2018-01-22 08:53 GMT
Find Nodes?
    Voting Booth?
    How did you see in the new year?

    Results (233 votes). Check out past polls.