1

I have a hash with a certain set of data. I need to manipulate the hash values so that I can get result like below:

Expected Output:

key_1=Cell1
Val_1=C3#C4#C1#C2

Script:

#!/usr/bin/perl

use strict; use warnings;

use Data::Dumper;
use List::Util qw /uniq/;

my %hash = (
        'Cell1' => {
                    'A' => [ 'C1','C2','C1','C2' ],
                    'B' => [ 'C3','C3','C4','C4' ]
        }
);

print Dumper(\%hash);

my $i = 0;

foreach my $key (keys %hash) {
    ++$i;
    print "key_$i=$key\n";
    foreach my $refs (keys %{ $hash{$key} }) {
        print "Val_$i=", join('#', uniq @{$hash{$key}{$refs}})."\n";    
    }
}

Current Output:

key_1=Cell1
Val_1=C3#C4
Val_1=C1#C2

How can I get the expected output here?

Artjom B.
  • 61,146
  • 24
  • 125
  • 222
vkk05
  • 3,137
  • 11
  • 25

2 Answers2

2

You can use an additional array (@cells) to store the values before you print:

foreach my $key (keys %hash) {
    ++$i;
    print "key_$i=$key\n";
    my @cells;
    foreach my $refs (keys %{ $hash{$key} }) {
        push @cells, @{$hash{$key}{$refs}};
    }
    print "Val_$i=", join('#', uniq @cells)."\n";    
}

Prints:

key_1=Cell1
Val_1=C3#C4#C1#C2

The order is not guaranteed since you retrieve the keys from a hash. You could use sort to make the order predicatable.

toolic
  • 57,801
  • 17
  • 75
  • 117
2

The shown code uses values for each key one at a time (for A, then for B ...) . Instead, assemble all values using map on the list of all keys

my $i = 0;
for my $key (keys %hash) { 
    ++$i;
    say "key_$i=$key";
    say "Val_$i=", 
        join "#", uniq map { @{ $hash{$key}->{$_} } } keys %{$hash{$key}};
}
zdim
  • 64,580
  • 5
  • 52
  • 81