【问题标题】:Why checking if the hash is empty fails?为什么检查哈希是否为空失败?
【发布时间】:2017-06-18 06:58:24
【问题描述】:

有很多关于如何check if a hash is empty 的参考资料。我在以下脚本中尝试了所有这些:

use strict;
use warnings;
use Data::Dumper;
   $Data::Dumper::Sortkeys = 1;

# Signals come...
my %items = (
    item_1 => {signal_1 => 'up',
               signal_2 => 'down',
               signal_3 => 'up',
              },
    item_2 => {signal_1 => 'down',
              },
    item_3 => {signal_1 => 'up',
               signal_3 => 'down',
               signal_4 => 'down',
               signal_5 => 'down',
              },
  );

# ... and signals go:
delete $items{'item_2'}->{'signal_1'};
# and sometimes all signals are gone from an item:
print Dumper(\%items);
# in that case we would like the signal count to show 0 (zero).
my %signals;
foreach my $item (sort keys %items){
  #$signals{$item} = 0;
  foreach my $signal (sort keys %{$items{$item}}){
    if   (not %{$items{$item}}) {print "HERE\n"; $signals{$item} = 0}
    elsif($items{$item}->{$signal} eq 'up')  {$signals{$item}++}
    elsif($items{$item}->{$signal} eq 'down'){$signals{$item}--}
  }
}
# unfortunately the item disappears completely!
print Dumper(\%signals);

似乎迭代器完全跳过了空哈希。我产生正确结果的唯一方法是将每个计数初始化为零(注释掉),并让它通过非空哈希递增/递减。

为什么……???

【问题讨论】:

  • @Toto 我认为问题是为什么没有item_2 => 0
  • @simbabque:好吧,我误会了:(
  • 如果有 X 个要迭代的键,则循环有 X 次迭代。是的,即使 X 为零也适用。您的“解决方法”实际上是处理这种情况的正确方法。

标签: perl hash is-empty


【解决方案1】:

如果哈希中没有键,则keys 返回一个空列表()。当您使用foreach 遍历一个空列表时,将永远不会调用循环体。所以你的print "HERE" 永远不会被联系到。这是正确的。

foreach (()) {
    print "foo";
}

__END__
(no output)

Perl 的 auto-vivification 在您第一次使用它们时会在哈希中为您创建值,而当您对它们进行数学运算时,值会以 0 开头。这就是为什么您可以在条件内的循环中添加和减去它们。

为了让它发挥作用,你已经用你的注释行做了正确的事情。

foreach my $signal (sort keys %{$items{$item}}){
    $signals{$item} = 0;
    if ( ...

现在您首先将每个键初始化为0。与上述隐式执行相同,只是每次都执行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-06
    • 2021-03-20
    • 1970-01-01
    • 1970-01-01
    • 2019-04-10
    • 1970-01-01
    • 1970-01-01
    • 2013-11-16
    相关资源
    最近更新 更多