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

I have the following script

my %nodemetrics; my @nodelist = qw(server1 server2); my @system_attributes = qw(memory cpu disk network); # Initialise the hash with zeros foreach $node (@nodelist) { foreach (@system_attributes){ $nodemetrics{$node}{$_} = 0; } } print Dumper(\%nodemetrics);

When I run this I get

$VAR1 = { 'server2' => { 'network' => 0, 'memory' => 0, 'disk' => 0, 'cpu' => 0 }, 'server1' => { 'network' => 0, 'memory' => 0, 'disk' => 0, 'cpu' => 0 } };

Now I run an external command which returns pipe delimited data for one server. I store this in an array. For example I might have:

$string="1024|2200|30|100"; @data = split(/\|/,$string);

How do I 'copy' this array into one of the servers data? In other words for a particular server I need to populate its attributes with this array.

I know I could set each attribute one by one but that's cumbersome for a large number of attributes

Replies are listed 'Best First'.
Re: Not sure how to populate a hash
by LanX (Saint) on Sep 24, 2014 at 10:06 UTC
    you could use a hash slice to populate many slots at once

    @$hashref{@keys}=@values

    With

    $hashref=$nodemetrics{$node}

    update

    Not sure why you prepopulate to 0, simply undef seems more robust and is easily done:

    @$hashref{@keys}=()

    HTH :)

    Cheers Rolf

    (addicted to the Perl Programming Language and ☆☆☆☆ :)

      Sorry Rolf

      I'm afraid I still dont get it. :-(

      By @keys do you mean @system_attributes?

      So I need to do this?

      @$hashref{@system_attributes}=@data;

        Hello aditya1977,

        In the spirit of TMTOWTDI, here’s a concise implementation of LanX’s hash slice solution:

        #! perl use strict; use warnings; use Data::Dump; my %nodemetrics; my @nodelist = qw(server1 server2); my @attributes = qw(memory cpu disk network); my $string = '1024|2200|30|100'; my @data = split /\|/, $string; @{ $nodemetrics{$_ } }{@attributes} = (0) x @attributes for @node +list; dd \%nodemetrics; @{ $nodemetrics{server1} }{@attributes} = @data; dd \%nodemetrics;

        Output:

        22:03 >perl 1027_SoPW.pl { server1 => { cpu => 0, disk => 0, memory => 0, network => 0 }, server2 => { cpu => 0, disk => 0, memory => 0, network => 0 }, } { server1 => { cpu => 2200, disk => 30, memory => 1024, network => 100 + }, server2 => { cpu => 0, disk => 0, memory => 0, network => 0 }, } 22:03 >

        Hope that helps,

        Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

        Why don't you try and see? :)

        Caution order matters!

        Cheers Rolf

        (addicted to the Perl Programming Language and ☆☆☆☆ :)

        PS: and plz have a look at the links provided.

        Hi aditya1977

        Lets try this one.

        use strict; use warnings; use Data::Dumper; my %nodemetrics; my @nodelist = qw(server1 server2); my @system_attributes = qw(memory cpu disk network); # Initialise the hash with zeros my ($node); foreach $node (@nodelist) { foreach (@system_attributes){ $nodemetrics{$node}{$_} = 0; } } print Dumper(\%nodemetrics); my $string="1024|2200|30|100"; my @data = split(/\|/,$string); my @keys = keys %{$nodemetrics{'server1'}}; my $hashref = $nodemetrics{'server1'}; @$hashref{@keys}=@data; $nodemetrics{'server1'}=$hashref; print Dumper (\%nodemetrics);

        All is well
Re: Not sure how to populate a hash
by karlgoethebier (Abbot) on Sep 24, 2014 at 14:43 UTC

    Another init:

    my %nodemetrics = map { $_ => { map { $_ => undef } @attributes } } @nodelist;

    Regards, Karl

    «The Crux of the Biscuit is the Apostrophe»