【问题标题】:perl hash derived from array does not work as expected从数组派生的 perl 哈希不能按预期工作
【发布时间】:2013-05-20 23:50:47
【问题描述】:

我在使用从数组派生的哈希时遇到了一些问题。对于我知道存在的元素,它未能通过“存在”测试。我写了小测试代码来确认这一点。这里是:

#!/usr/local/bin/perl

my @sieve = (2, 3, 5, 7, 11, 13, 17, 19);
my %sieve_hash = @sieve;


foreach $prime (@sieve) {
    if (exists($sieve_hash{$prime})) {
    print "$prime exists!\n";
    } else {
    print "$prime DOES NOT exist.\n";
    }
}

这是示例输出:

2 exists!
3 DOES NOT exist.
5 exists!
7 DOES NOT exist.
11 exists!
13 DOES NOT exist.
17 exists!
19 DOES NOT exist.

我做错了什么?

【问题讨论】:

    标签: perl hash


    【解决方案1】:

    分配给散列时,需要一个交替键和值的列表。以下将解决您的问题:

    my %sieve_hash = map { $_ => 1 } @sieve;
    

    有了以上内容,一个简单的真实性测试(而不是存在性测试)就足够了。但是由于您使用的是存在测试,因此您可以通过使用以下分配 undef 而不是 1 来节省一些内存:

    my %sieve_hash;
    @sieve_hash{ @sieve } = ();
    

    my %sieve_hash;
    $sieve_hash{$_} = undef for @sieve;
    

    不过,我发现真值测试要优雅得多。

    【讨论】:

    • 谢谢。这很好地解释了这一点。
    【解决方案2】:

    当您将数组分配给哈希时,偶数索引元素,例如$sieve[0]、$sieve[2] 成为哈希键,奇数元素 $sieve[1]、$sieve[3] 等成为哈希值。您会注意到输出中的模式,其中只有每个其他元素(第 0 个、第 2 个、第 4 个)作为哈希中的键“存在”。

    使用 Data::Dumper 查看发生了什么:

    #!/usr/bin/perl
    
    use Data::Dumper;
    
    my @sieve = (2, 3, 5, 7, 11, 13, 17, 19);
    my %sieve_hash = @sieve;
    
    print STDERR "Your array:\n";
    print Dumper \@sieve;
    
    print STDERR "Your hash:\n";
    print Dumper \%sieve_hash;
    
    
    
    Your array:
    $VAR1 = [
              2,
              3,
              5,
              7,
              11,
              13,
              17,
              19
            ];
    Your hash:
    $VAR1 = {
              '11' => 13,
              '17' => 19,
              '2' => 3,
              '5' => 7
            };
    

    【讨论】:

      【解决方案3】:

      当你说

      my %sieve_hash = @sieve;
      

      它以数组的每个其他元素为键,其他元素为值。

      所以你的哈希看起来和它是由以下构造的一样:

      my %sieve_hash = (
        2 => 3,
        5 => 7,
        ... and so on
      );
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-04-28
        • 1970-01-01
        • 2011-10-01
        • 2011-04-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多