在使用“each”迭代哈希时添加新成员

Posted

技术标签:

【中文标题】在使用“each”迭代哈希时添加新成员【英文标题】:Adding new members while iterating a hash with "each" 【发布时间】:2013-07-08 10:41:54 【问题描述】:

在 perl 5.10.1 中,是否可以在使用 each 运算符迭代哈希时向哈希添加新成员?

就像在这段代码中(为谷歌图表准备数据),我有一个数组的哈希值,我试图移动每个数组的最后一个元素:

sub split_aclr($) 
        my $csvData = shift;

        while (my ($csv, $href) = each %$csvData) 
                next unless $csv =~ /_ACLR_/i;
                my $len = scalar @$href->MEASUREMENT;

                if ($len > 1 && $href->MEASUREMENT->[$len - 1] eq 'CARRIER_CHANNEL') 
                        while (my ($key, $arr) = each %$href) 
                                my $moved = pop @$arr;
                                $csvData$csv . '_CARRIER_CHANNEL' = $key => [ $moved ];
                        
                
        

【问题讨论】:

【参考方案1】:

在使用each 迭代散列时添加或删除条目通常是不安全的。如果您想这样做,最好将要迭代的键的显式列表保存到数组中,然后对其进行循环。

而不是

while (my $k, $v) = each %hash) 
  $hash"foo_$k" = $v;

my @keys = keys %hash;
for my $k (@keys) 
  my $v = $hash$k;
  $hash"foo_$k" = $v;

【讨论】:

谢谢!可以在代码中省略 @keys 而只使用 for my $k (keys %hash) 吗? @AlexanderFarber 是的,在这种情况下,@keys 可以省略。我使用了一个额外的变量来使密钥列表的复制变得清晰。但是,如果要修改正在迭代的数组,则不能使用 foreach 循环。【参考方案2】:

这不安全。如果你这样做了,你会得到一个警告:“插入后在哈希上使用each()而不重置哈希迭代器会导致未定义的行为。”

【讨论】:

【参考方案3】:

documentation for each() 对此非常清楚。

如果您在迭代时添加或删除哈希元素 它,您可能会跳过或重复条目,所以不要。

【讨论】:

以上是关于在使用“each”迭代哈希时添加新成员的主要内容,如果未能解决你的问题,请参考以下文章

Ruby迭代器

迭代时无意中将键添加到哈希

如何在 jQuery .each() 的每次迭代之间添加暂停?

迭代时添加到数组

集合foreach迭代时,边迭代边删除,只能使用迭代器删除,不能使用集合删除,否则会导致并发修改异常for-each和Iterator的选择

如何在没有 ConcurrentModificationException 的情况下使用 for-each 循环进行迭代时修改集合? [复制]