遍历Perl哈希键的最安全方法是什么? [英] What's the safest way to iterate through the keys of a Perl hash?

查看:237
本文介绍了遍历Perl哈希键的最安全方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我有一堆(键,值)对的Perl哈希,迭代所有键的首选方法是什么?我听说使用每个都可能在某种程度上具有意想不到的副作用。那么,这是真的,并且是以下两种方法中最好的一种,或者有更好的方法吗?

 #方法1 
while(my($ key,$ value)= each(%hash)){
#Something
}

#方法2
foreach my $ key(key(%hash)){
#Something
}


解决方案

经验法则是使用最适合您需求的功能。



如果您只是想要钥匙而不计划使用keys():

  foreach my $ key(keys %hash){...} 

如果您只想使用这些值,请使用values():

  foreach my $ val(values%hash){...} 

如果您需要键值,请使用each():

 键%hash; #重置内部迭代器,以便前面的each()不影响循环
while(my($ k,$ v)= each%hash){...}
除了,以便在迭代过程中删除当前键),则可以使用 那么你不能使用each()。例如,使用keys()创建一组具有doubled值的新大写键的代码可以正常工作:

 %h = (a => 1,b => 2); 

foreach my $ k(keys%h)
{
$ h {uc $ k} = $ h {$ k} * 2;
}

产生预期的结果散列值:
$ b (a => 1,A => 2,b => 2,B => 4)

但是使用each()来做同样的事情:

 %h =(a => 1,b => 2); 

键%h;
while(my($ k,$ v)= each%h)
{
$ h {uc $ k} = $ h {$ k} * 2; # 馊主意!
}

以难以预测的方式产生不正确的结果。例如:

 (a => 1,A => 2,b => 2,B => 8)

然而,这是安全的:

 键%h; 
while(my($ k,$ v)= each%h)
{
if(...)
{
delete $ h {$ k} ; #这是安全的
}
}

所有这些都在perl文档:

 %perldoc -f键
perldoc -f每个


If I have a Perl hash with a bunch of (key, value) pairs, what is the preferred method of iterating through all the keys? I have heard that using each may in some way have unintended side effects. So, is that true, and is one of the two following methods best, or is there a better way?

# Method 1
while (my ($key, $value) = each(%hash)) {
    # Something
}

# Method 2
foreach my $key (keys(%hash)) {
    # Something
}

解决方案

The rule of thumb is to use the function most suited to your needs.

If you just want the keys and do not plan to ever read any of the values, use keys():

foreach my $key (keys %hash) { ... }

If you just want the values, use values():

foreach my $val (values %hash) { ... }

If you need the keys and the values, use each():

keys %hash; # reset the internal iterator so a prior each() doesn't affect the loop
while(my($k, $v) = each %hash) { ... }

If you plan to change the keys of the hash in any way except for deleting the current key during the iteration, then you must not use each(). For example, this code to create a new set of uppercase keys with doubled values works fine using keys():

%h = (a => 1, b => 2);

foreach my $k (keys %h)
{
  $h{uc $k} = $h{$k} * 2;
}

producing the expected resulting hash:

(a => 1, A => 2, b => 2, B => 4)

But using each() to do the same thing:

%h = (a => 1, b => 2);

keys %h;
while(my($k, $v) = each %h)
{
  $h{uc $k} = $h{$k} * 2; # BAD IDEA!
}

produces incorrect results in hard-to-predict ways. For example:

(a => 1, A => 2, b => 2, B => 8)

This, however, is safe:

keys %h;
while(my($k, $v) = each %h)
{
  if(...)
  {
    delete $h{$k}; # This is safe
  }
}

All of this is described in the perl documentation:

% perldoc -f keys
% perldoc -f each

这篇关于遍历Perl哈希键的最安全方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆