2017-02-01 14 views
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); 

イテレータが空のハッシュを完全にスキップしているようです。正しい結果を出す私の唯一の方法は、各カウントをゼロ(コメントアウト)に開始し、それが空でないハッシュによって増減されるようにすることでした。

なぜですか... ???

+1

@Toto私は質問がなぜ 'item_2 => 0'でないのかと思います。 – simbabque

+0

@simbabque:OK、私は誤解していました:( – Toto

+0

ループを繰り返すXキーがある場合、ループのX反復がありますが、これはXがゼロの場合でも適用されます。状況を処理する。 – ikegami

答えて

4

ハッシュにキーがない場合、keysは空のリスト()を返します。空のリストの上にforeachを反復すると、ループの本体が決して呼び出されません。したがって、print "HERE"には決して届きません。これは正しいです。あなたがそれらを最初に使用するとき

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

__END__ 
(no output) 

Perlの自動vivificationはあなたのためのハッシュの値を作成し、あなたがそれらに数学を行うときの値が0として開始。そのため、条件内でループ内でそれらを追加したり除外したりすることができます。

これを機能させるには、あなたのコメントアウトされた行で既に正しいことをしています。

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

ここですべてのキーを最初に0に初期化します。それは暗黙のうちに上記のように同じことをしますが、毎回それを実行します。

関連する問題