简体   繁体   中英

perl hash of hashes - for eacy key group inner keys and respective values

I have a hash of hashes retrieved from json and I am trying to flatten hash, group and print values. That is, for each key1 group all keys and respective values.Trying to achieve this in perl using below code but, it is printing individual values each ID and names but not grouped values. Could you please help me how to group and print keys and values.

Data:

VAR1= {
        'ID1' => {'Name1' => {'Address1' => {'Mod1' => ['pol1']}},
                  Name2' => {'Address1' => {'Mod2' => ['pol2']}}},
        'ID2' => {'Name3' => {'Address3' => {'Mod3' => ['pol3']}}},
        'ID3' => {'Name4' => {'Address4' => {'Mod4' => ['pol1, pol2, pol3']}}}
}

Expected Output:

ID1 => [Name1,Address1,mod1(pol1), Name2,Address1,mod2(pol2)],
ID2 => [Name3,Address3,mod3(pol3)],
ID3 => [Name4,Address4,mod4(pol1,pol2,pol3)]

Code1:

for my $id (@id_list) {
     foreach my $item (sort (slurp(\%{$new{$id}}))) {
     my $data = join(',', @$item);
     print "data..  $data\n";
     push(@results,$data);
  } 
}

print map {"$_"}  @results;

Code2:

foreach my $id (sort keys %new){
   foreach my $name (keys %{$new{$id} }) {
      foreach my $address (keys %{$new{$id}{$name}}) {
         foreach my $mod (keys %{$new{$id}{$name}{$address}) {
            foreach my $value (@{$new{$id}{$name}{$address}{$mod}}) {
               my $sp = ":";
               my $reasons = join(',',$id,$name,$address,$mod,$value.$sp);
               push (@rea, $reasons);
            }
         }
      }
   }
}

With such a nested structure you want to go systematically, like in your " Code2 ".

use warnings;
use strict;
use feature qw(say);

my %id_list = ( 
    ID1 => { 
        Name1 => {'Address1' => {'Mod1' => ['pol1']}}, 
        Name2 => {'Address1' => {'Mod2' => ['pol2']}}
    },  
    ID2 => { 'Name3' => {'Address3' => {'Mod3' => ['pol3']}} },
    ID3 => { 'Name4' => {'Address4' => {'Mod4' => ['pol1, pol2, pol3']}} }
);

my (%flattened, @ar, $modvals);
foreach my $id (sort keys %id_list){
    foreach my $name (keys %{$id_list{$id} }) {
        foreach my $address (keys %{$id_list{$id}{$name}}) {
            foreach my $mod (keys %{$id_list{$id}{$name}{$address}}) {
                $modvals = "$mod(" . 
                    join(',', @{$id_list{$id}{$name}{$address}{$mod}})
                    . ')';
                $modvals =~ s/,$//; # strip the last comma
                push @ar, $name, $address, $modvals;
            }   
        }   
    }
    $flattened{$id} = [ @ar ];
    @ar = ();
}

say "$_ => @{$h{$_}}" for sort keys %flattened;

Output

ID1 => Name1 Address1 Mod1(pol1) Name2 Address1 Mod2(pol2)
ID2 => Name3 Address3 Mod3(pol3)
ID3 => Name4 Address4 Mod4(pol1, pol2, pol3)

This generates the string for mod3 as (pol1, ...) -- as given in input, as a single string. If that is chaged to a list of pol in input, the spaces between pol 's will be gone in output.

A hash with id keys and array ref with respective entries is generated.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM