为什么检查哈希是否为空失败?
Why checking if the hash is empty fails?
关于如何 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);
迭代器似乎完全跳过了空散列。我产生正确结果的唯一方法是将每个计数初始化为零(注释掉)并让它成为 incremented/decremented 非空哈希值。
为什么是...???
如果散列中没有键,则 keys
returns 一个空列表 ()
。当你用 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
。就像上面描述的那样隐式地做同样的事情,它只是每次都这样做。
关于如何 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);
迭代器似乎完全跳过了空散列。我产生正确结果的唯一方法是将每个计数初始化为零(注释掉)并让它成为 incremented/decremented 非空哈希值。
为什么是...???
如果散列中没有键,则 keys
returns 一个空列表 ()
。当你用 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
。就像上面描述的那样隐式地做同样的事情,它只是每次都这样做。