|
如果想迭代hash 的每一个元素(如,检查每一个元素),一种通常的方法是使用each 函数,它将返回key/value 对的2元素
列表◆。当对同一个hash 函数进行一次迭代时,将返回下一个key/value 对,直到所有的元素均被访问。如果没有更多的
key/value 对,则each 函数将返回空表。
◆另一种方法是使用foreach,这将在本节末尾介绍。
实践中,一般只在while 循环中使用each:
while (($key, $value) = each %hash){
print “$key => $value\n”;
}
上述代码中,首先,each %hash 将从hash 中返回一个key/value 对;假设key 为“c”,value 为3,则列表为(“c”,3)。这个
列表赋给($key, $value),现在$key 为“c”,而$value 为3。
但上述赋值语句是作为while 循环的条件表达式,这是在标量context 中。(更确切的说,这是boolean context,其希望得到
true/false 值,但boolean context 是一种特殊的标量context)。列表赋值语句在标量context 中返回的是元素的个数,在本例
中,是2。由于2是一个true 值,我们进入循环,然后输出c=>3。
第二次进入循环时,each%hash 得到一个新的key/value 对,例如,返回(“a”,1)。(Perl 会返回一个不同的key/value 对,因为
Perl 能对其追踪。按照行话来讲,每一个hash 都有一个iterator(迭代器)。◆)这两元素被存放在($key, $value)中。由于元
素个数也为2,为真值,则进入while 循环,输出a => 1。
◆由于每一个hash 都有一个私有的迭代器(iterator),因此,使用each 的循环是可以嵌套的,因为不同的hash 有不同的迭代器(iterator)。
虽然这只是脚注,但我们也应当告诉你,你可以通过使用keys 或values 函数,重置迭代器(iterator)。如果新列表加入到此hash 中,或
者each 函数迭代到最后一个元素,也会重置迭代器(iterator)。另一方面,如果在迭代时加入新的key/value 对,通常是一个坏主意,这
不会重置迭代器(iterator)。但很可能混淆你,以及维护人员。
再进行一次循环,得到结果b=>2。
现在没有剩余的元素了。当Perl 执行each %hash,由于没有key/value 对,因此返回空列表。空列表赋给($key, $value),$key
得到undef, $value 仍然为undef。
◆由于是在列表context 中,其返回的不是表明失败的undef,因为undef 是一个元素的列表(undef)而零元素非空列表( )。
我们并不需要关心上面的过程,因为它是作为一个整体在while 循环的条件部分被求值的。列表在一个标量context 中将返
回其元素的个数;在本例中,为0。由于0时false 值,则while 循环结束,执行程序的剩余部分。
当然,each 返回的key/vlaue 对,顺序是混乱的(它其顺序和keys 和values 函数返回的顺序相同)。如果想将其按序排放,
可以对它们排序(使用sort),大致如下:
foreach $key (sort keys %hash){
$value =$hass{$key};
print “$key => $value\n”;
#也可以不使用额外的临时变量$value
#print “$key => $hash{key}\n”;
}
|
|