在数组的散列中拆分散列

Ped*_*roA 0 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;
Run Code Online (Sandbox Code Playgroud)

但是发出警告:

Can't use string ("AAAAAAAAAA") as an ARRAY ref while "strict refs" in use
Run Code Online (Sandbox Code Playgroud)

提前致谢.

TLP*_*TLP 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
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

$_ = [ split // ] for values %hash1, values %hash2;
Run Code Online (Sandbox Code Playgroud)

这里我们(ab)使用这样一个事实:for循环中的元素与原始变量别名,并且只是以与上面相同的方式覆盖值.

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

for my $value (values %hash1, values %hash2) {
    $value = [ split //, $value ];
}
Run Code Online (Sandbox Code Playgroud)

  • 我同意,对于像我这样仍在学习`perl`的人来说,它更容易.谢谢@TLP. (2认同)