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

반복자가 빈 해시를 완전히 건너 뛴 것으로 보입니다. 정확한 결과를 내기위한 나의 유일한 방법은 각 카운트를 0으로 초기화 (주석 처리)하고 비어 있지 않은 해시에 의해 증가/감소되도록하는 것이 었습니다.

왜 그런가요? ???

+1

@ 토토 나는 왜 'item_2 => 0'이 없냐고 묻는다. – simbabque

+0

@simbabque : 알겠습니다, 오해했습니다. ( – Toto

+0

반복 할 X 키가있는 경우 루프의 X 반복이 있습니다. 예, X가 0 일 때도 적용됩니다. "해결 방법"은 실제로 적절한 방법입니다. 상황을 처리. – ikegami

답변

4

해시에 키가없는 경우 keys은 빈 목록 ()을 반환합니다. 빈 목록에 foreach을 반복 할 때 루프 본문은 호출되지 않습니다. 따라서 귀하의 print "HERE"에 결코 도달 할 수 없습니다. 이 말이 맞습니다. 당신이 그 (것)들에게 처음 사용할 때

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

__END__ 
(no output) 

펄의 자동 vivification 당신을위한 해시 값을 생성하고, 당신이 그들에 수학을 수행 할 때 값이 0로 시작합니다. 따라서 조건 내에서 루프에 추가 및 제외 할 수 있습니다.

제대로 작동하려면 이미 주석 처리 된 행을 사용하십시오.

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

이제 모든 키를 0으로 초기화하십시오. 그것은 암묵적으로 위에서 설명한 것과 똑같은 일을합니다. 단지 매번 그렇게합니다.