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

Hello,

I have a three dimensional hash with info like below.

%LPAR_config = ( 'lpar1' => { 'profile1' => { ... }, 'profile2' => { ... }, 'frame' => 'frame1', 'lpar_id' => '1' } 'lpar2' => { 'profile1' => { ... }, 'profile2' => { ... }, 'frame' => 'frame1', 'lpar_id' => '2' 'lpar3' => { 'profile1' => { ... }, 'profile2' => { ... }, 'frame' => 'frame2', 'lpar_id' => '1' } 'lpar4' => { 'profile1' => { ... }, 'profile2' => { ... }, 'frame' => 'frame2', 'lpar_id' => '2' ... )

I've skipped the original list, as it has 191 lpars and each a lot of info. At one point in the program I need to get the name of the lpar from frame2 with lpar_id 1.

I'm now looping trough the keys to check if the lpar with name $key is on frame "frame2" and has lpar_id 1.
As I can skip most of the entries I was wondering, is there an easier way to get the key based on the content of the values of $key

On a related note, is there an easy way (read without looping myself) to copy a subset of the hash (for example all lpars on frame2) to another hash? This would speed-up the script, as most data is needed of just 1 frame (of 14 available)

Replies are listed 'Best First'.
Re: Easy way to find data in hash or get subset of hash
by roboticus (Chancellor) on Mar 05, 2013 at 15:42 UTC

    T_I:

    I'm probably misunderstanding your question, but is this what you're asking for?

    if (! exists $LPAR_config{$key}) { die "We don't have $key!\n"; } if ($LPAR_config{$key}{frame} eq "frame2" and $LPAR_config{$key}{lpar_id} == 1) { print "Found it!\n"; }

    ...roboticus

    When your only tool is a hammer, all problems look like your thumb.

Re: Easy way to find data in hash or get subset of hash
by Athanasius (Archbishop) on Mar 05, 2013 at 15:49 UTC

    To avoid the loop, put the conditions given by roboticus, above, into the block of a grep:

    #! perl use strict; use warnings; use Data::Dump; my %LPAR_config = ( lpar1 => { profile1 => {}, profile2 => {}, frame => 'frame1', lpar_id => '1', }, lpar2 => { profile1 => {}, profile2 => {}, frame => 'frame1', lpar_id => '2', }, lpar3 => { profile1 => {}, profile2 => {}, frame => 'frame2', lpar_id => '1' }, lpar4 => { profile1 => {}, profile2 => {}, frame => 'frame2', lpar_id => '2', }, ); my @matches = grep { $LPAR_config{$_}->{frame } eq 'frame2' && $LPAR_config{$_}->{lpar_id} eq '1' } keys %LPAR_c +onfig; dd @matches;

    Output:

    1:43 >perl 560_SoPW.pl "lpar3" 1:44 >

    Hope that helps,

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

      Thanks, that helped a lot. It's easy readable and maintainable.

Re: Easy way to find data in hash or get subset of hash
by Anonymous Monk on Mar 05, 2013 at 15:33 UTC

    As I can skip most of the entries I was wondering, is there an easier way to get the key based on the content of the values of $key

    Easier than what?

    See Data::Diver

    On a related note, is there an easy way (read without looping myself) to copy a subset of the hash (for example all lpars on frame2) to another hash? This would speed-up the script, as most data is needed of just 1 frame (of 14 available)

    Yes, write a function, then call it as many times as you want --- the function does the looping, so you don't have to repeat it yourself -- see Data::Visitor::Callback