2009-07-14 4 views
6

나는 펄에서 해시를 배우려고하는 간단한 스크립트를 가지고있다.Perl의 each()가 두 번째로 전체 해시를 반복하지 않는 이유는 무엇입니까?

#!/usr/bin/perl 

my %set = (
    -a => 'aaa', 
    -b => 'bbb', 
    -c => 'ccc', 
    -d => 'ddd', 
    -e => 'eee', 
    -f => 'fff', 
    -g => 'ggg' 
); 

print "Iterate up to ggg...\n"; 
while (my ($key, $val) = each %set) { 
    print "$key -> $val \n"; 
    last if ($val eq 'ggg'); 
} 
print "\n"; 

print "Iterate All...\n"; 
while (my ($key, $val) = each %set) { 
    print "$key -> $val \n"; 
} 
print "\n"; 

나는 출력에 의해 놀랜다 : -

Iterate upto ggg... 
-a -> aaa 
-c -> ccc 
-g -> ggg 

Iterate All... 
-f -> fff 
-e -> eee 
-d -> ddd 
-b -> bbb 

내가 처음 출력은 내부 순서에 따라 'N'요소가 될 수 있도록 키가 해시 이해합니다. 그런데 왜 나중에 배열을 반복 할 수 없습니까? 뭐가 문제 야 ?

덕분에,

답변

18

each 반복을 추적하기 위해 해시와 연관된 포인터를 사용합니다. 첫 번째 while이 두 번째 while 루프와 다르다는 사실을 알지 못하며, 두 번째 while 루프 사이에 동일한 포인터를 유지합니다.

대부분의 사람들은 대신 keys 말인가,이 (다른) 이유 each 피하기 :

for my $key (sort keys %hash){ 
    say "$key => $hash{$key}"; 
} 

어쨌든 :

for my $key (keys %hash){ 
    say "$key => $hash{$key}"; 
} 

이것은 당신이뿐만 아니라, 반복 순서를 제어 할 수 루프를 일찍 끝내려면 each을 피해야합니다.

사실 함수 프로그래밍 옹호자는 숨겨진 상태의 단점을 지적 할 기회를 가져야합니다. 상태 비 저장 작업 ("테이블의 각 쌍에 대한 루프")은 실제로 꽤 상태가 좋습니다.

+0

감사를 반복하는 코드에 키 % 설정을 사용할 수 있습니다. BTW, '각'을 처음부터 다시 설정할 수 있습니까? –

+0

"% hash = % hash"가 작동하는 것 같습니다. – jrockway

+6

(perlfaq4는 void 컨텍스트에서 해시의 "keys"를 호출하는 것을 제안하므로 불필요한 복사를 피할 수 있습니다.) – jrockway

10

perldoc -f each 

에 perldoc을 읽을 수 해시가 완전히 판독 될 때, 널 어레이 "(할당 된 경우 거짓 (0) 값을 생성 함)에서 문맥에 반환하고, undef "를 사용한다. 그 다음에 "each"를 호출하면 다시 반복이 시작됩니다. 프로그램의 모든 "each", "keys"및 "values"함수 호출에 의해 공유되는 각 해시에 대해 반복자가 있습니다. 해시에서 모든 요소를 ​​읽거나 "HASH 키"또는 "HASH 값"을 평가하여 재설정 할 수 있습니다.

때문에, 당신은 (인해 당신 "마지막"문에) 다시

print "Iterate upto ggg...\n"; 
while (my ($key, $val) = each %set) { 
    print "$key -> $val \n"; 
    last if ($val eq 'ggg'); 
} 
print "\n"; 
keys %set; 
print "Iterate All...\n"; 
while (my ($key, $val) = each %set) { 
    print "$key -> $val \n"; 
} 
print "\n";