修改密钥(如果已存在)

时间:2013-08-26 16:59:19

标签: perl hash key unique exists

我正在编写一段代码,为每个密钥创建一个HoA并循环遍历。下面的代码段显示了我遇到的问题的基本示例。

#!/usr/bin/perl 
use strict;
use warnings;

my @array1 = qw (1 1 3 4 5); # Note that '1' appears twice
my @array2 = qw (a b c d e);
my @array3 = qw (6 7 8 9 10);
my @array4 = qw (f g h i j);

my %hash;   
push @{$hash{$array1[$_]}}, [ $array2[$_], $array3[$_], $array4[$_] ] for 0 .. $#array1;

for my $key (sort keys %hash) {
    my ($array2, $array3, $array4) = @{$hash{$key}[-1]};
    print "[$key] $array2\t$array3\t$array4\n"; 
}

输出:

[1] b   7   g
[3] c   8   h
[4] d   9   i
[5] e   10  j

对于我实际使用的数据(与此示例相反)我一直在使用我刚才意识到的并不是唯一的密钥,因此,如上所述,我最终会覆盖非uniqe密钥。我主要使用这些值作为键,以便以后按它们排序。

我的问题是:

A)我可以为每个键unless (exists $hash{$array1})执行上述任务,在这种情况下我可以修改它

B)有没有办法按这些值排序,在这种情况下我可以使用另一个非冗余密钥。

谢谢!

1 个答案:

答案 0 :(得分:2)

  

所以,如上所述,我最终会覆盖非uniqe键

你不是。让我们打印出该哈希的全部内容:

for my $key (sort { $a <=> $b } keys %hash) {  # sort numerically!
  for my $array (@{ $hash{$key} }) {           # loop over all instead of $hash{$key}[-1] only
    say "[$key] " . join "\t", @$array;
  }
}

输出:

[1] a   6       f
[1] b   7       g
[3] c   8       h
[4] d   9       i
[5] e   10      j

如果您正在构建像

这样的哈希值,那么您将覆盖这些值
$hash{$array1[$_]} = [ $array2[$_], $array3[$_], $array4[$_] ] for 0 .. $#array1;

(并将其打印为)

for my $key ( ... ) {
  say "[$key] " . join "\t", @{ $hash{$key} };
}

即分配而不是push

如果您想保留为每个键分配的第一个值,请使用//=运算符(如果undef则分配)。