将数组转换为哈希值,其中键的值不等长

时间:2011-10-11 13:50:36

标签: perl

我喜欢将数组转换为哈希值。但是,每个键的值都不相等。

让我说我有

my @array = qw( A 0 B 1 2 3 4 c 5 d 6 7);

现在我喜欢使用字母作为键,并且每个这样的字母/键使用以下数字作为它们的值。因此,@array应转换为%hash,如下所示

my %hash = ( A => [0],
             B => [1, 2, 3, 4],
             c => [5],
             d => [6, 7]
    );

对我而言,困难在于每个键值的长度不等。

4 个答案:

答案 0 :(得分:6)

这是一种方法:

#!/usr/local/bin/perl 
use Data::Dump qw(dump);
use strict;
use warnings;

my @array = qw( A 0 B 1 2 3 4 c 5 d 6 7);
my %hash;
my $key;
foreach (@array) {
    if (/^\D+$/) {
        $key = $_;
        $hash{$key} = [];
    } else {
        push @{$hash{$key}}, $_;
    }
}
dump %hash;

<强>输出:

("A", [0], "c", [5], "d", [6, 7], "B", [1 .. 4])

答案 1 :(得分:4)

对于这个具体的例子,然后是一些评论

my $hash = {};
my @array = qw( A 0 B 1 2 3 4 c 5 d 6 7);
my $key;
foreach (@array) {
    if (/\D/) {
        $key = $_;
        next;
    } else {
        push @{$hash->{$key}}, $_;
    }
}

如果你想在调试器中玩:

$ perl -de 0

  DB<18>  @array = qw( A 0 B 1 2 3 4 c 5 d 6 7);
  DB<19> $hash={}
  DB<20> foreach(@array){if(/\D/){$key=$_;next}else{push @{$hash->{$key}},$_}}
  DB<21> x $hash
0  HASH(0x347e568)
  'A' => ARRAY(0x348fee8)
    0  0
  'B' => ARRAY(0x346f188)
    0  1
    1  2
    2  3
    3  4
  'c' => ARRAY(0x34cefb0)
    0  5
  'd' => ARRAY(0x346f1e8)
    0  6
    1  7

注释:除非您的密钥提供有关值是标量还是数组引用的信息,否则最好具有相同类型的所有值(在本例中为arrayref)

您想检查最后一个键是否有值,并决定是否要初始化为undef。

答案 2 :(得分:2)

或使用map

my @a = qw{a 1 2 3 b 4 5 6 C 7 8 9};
my ($key, %h);
map {  /^[a-z]$/i  and  $key = $_  or  push(@{$h{$key}}, $_)  } @a;

Perl不是很有趣吗?

答案 3 :(得分:2)

比以前提供的解决方案稍微简单一些:

my @array = qw( A 0 B 1 2 3 4 c 5 d 6 7);
my %hash;
my $values;
for (@array) {
   if (/\D/) {
      $values = $hash{$_} = [];
   } else {
      push @$values, $_;
   }
}