在数组的散列中拆分散列

时间:2014-08-05 18:31:31

标签: perl perl-data-structures

我有三个哈希,我想将每个哈希分解成一个Hash of Arrays。每个都可以通过split函数传递给子程序,但是这需要调用3次相同的子程序。我试图遍历每个哈希并将它们拆分但没有成功。是否可以在不调用子程序的情况下执行此操作?我试过的代码是:

#!/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;

但发出警告:

Can't use string ("AAAAAAAAAA") as an ARRAY ref while "strict refs" in use

提前致谢。

2 个答案:

答案 0 :(得分:9)

您的错误在于您获取的密钥$ref->{$key}的值为AAAAAAA等,并将其用作@{ ... }大括号的参考。您需要直接分配到$ref->{$key}

由于您要将原始值拆分为列表,因此需要一个数组来存储它。您可以通过使用命名数组,词法范围或匿名数组来执行此操作。我的选择是使用匿名数组,但命名数组可能看起来更具可读性:

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
    }
}

这个过程会覆盖原始值,但我认为这就是你想要的。

实现同样目标的更直接的方法是:

$_ = [ split // ] for values %hash1, values %hash2;

这里我们(ab)使用for循环中的元素对原始变量别名的事实,并简单地以与上面相同的方式覆盖值。

如果压缩格式是不需要的,则更详细的替代方法是:

for my $value (values %hash1, values %hash2) {
    $value = [ split //, $value ];
}

答案 1 :(得分:1)

假设我正确理解了你想做什么,你可以使用hash slicing并执行以下操作:

#!/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 ) {
    my @keys = keys %$ref;
    @$ref{@keys} = map { [split //, $ref->{$_}] } @keys;
}

print Dumper \%hash1;
print Dumper \%hash2;

这就像写作:

foreach my $ref ( \%hash1, \%hash2 ) {
    my @keys = keys %$ref;
    foreach my $key (@keys) {
        my @arr = split //, $ref->{$key};
        $ref->{$key} = \@arr;
    }
}

更简单。

相关问题