【问题标题】:Adding new members while iterating a hash with "each"在使用“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 ]};
                        }
                }
        }

}

【问题讨论】:

    标签: hash perl perl5.10


    【解决方案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() 对此非常清楚。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-18
        • 1970-01-01
        • 1970-01-01
        • 2016-04-07
        • 1970-01-01
        • 2023-03-28
        • 2023-04-07
        • 2016-06-23
        相关资源
        最近更新 更多