I have three hashes that I would like to explode each one into a Hash of Arrays. Each one could be passed into a subroutine with a split function, but this requires the same subroutine to be called 3 times. I have tried to iterate through each hash and them split it but without success. Is it possible to do this without calling a subroutine? The code I have tried is:
#!/usr/bin/perl
use warnings;
use strict;
use Data::Dumper;
my %hash1 = (
A => "AAAAAAAAAA",
B => "AAAAANAAAA",
C => "AAAAAXAAAA",
D => "AAXAAAAAAA",
E => "AAAAAAAAAX",
);
my %hash2 = (
F => "BBBBBBBBBB",
G => "BBBBBBBBBB",
H => "BBXBBBBBBB",
I => "BBBBBBBBBB",
J => "AAAAANAAAA",
);
foreach my $ref ( \%hash1, \%hash2 ) {
while ( my ($key, $value) = each %$ref) {
@{ $ref->{$key} } = split (//, $value );
}
}
print Dumper %hash1;
but gives the warning:
Can't use string ("AAAAAAAAAA") as an ARRAY ref while "strict refs" in use
Thanks in advance.
Your mistake is that you are taking the value of the key $ref->{$key}
which is AAAAAAA
etc, and using it as a reference with the @{ ... }
braces. You need to assign to $ref->{$key}
directly.
Since you are splitting the original value into a list, you need an array to store it. You can do this either by using a named array, lexically scoped, or an anonymous array. My choice would be to use an anonymous array, but a named array might appear more readable:
foreach my $ref ( \%hash1, \%hash2 ) {
while ( my ($key, $value) = each %$ref) {
$ref->{$key} = [ split (//, $value ) ]; # using anonymous array
# my @list = split (//, $value );
# $ref->{$key} = \@list; # using named array
}
}
This process would overwrite the original values, but I assume that is what you want.
A more direct way to achieve the same thing would be this:
$_ = [ split // ] for values %hash1, values %hash2;
Here we are (ab)using the fact that the elements in a for
loop are aliased to the original variables, and simply overwriting the values the same way we did above.
If the compressed format is unwanted, a more verbose alternative would be:
for my $value (values %hash1, values %hash2) {
$value = [ split //, $value ];
}