【问题标题】:perl - operations allowed on array while iterating through itperl - 遍历数组时允许的操作
【发布时间】:2014-10-23 07:48:12
【问题描述】:

在遍历数组时允许对数组进行哪些操作? 是否可以在不混淆迭代器的情况下移动/取消移动、弹出/推送、删除元素?

从哈希中添加/删除键值对有什么不同吗?

感谢您的帮助。

【问题讨论】:

  • 当然。我试图通过不重新创建另一个数据结构来简化多个数组的比较。然而,我认为对我有用的东西对你来说不一定有用,反之亦然。
  • 您可以使用 grep/map 过滤/转换/添加元素到列表,并将其分配回数组。

标签: arrays perl perl-hash


【解决方案1】:

正如 ysth 已经指出的那样,在直接迭代其元素时尝试修改数组是不明智的。

但是,如果确实想根据元素值修改数组,诀窍是按反向索引顺序进行。

例如,假设我有一个数字数组。我想修改数组,以便每个 4 的倍数在其后插入一个字符串,并删除每个 5 的倍数。我会使用以下方法来完成:

use strict;
use warnings;

my @array = ( 1 .. 20 );

for my $i ( reverse 0 .. $#array ) {
    # Insert after multiples of 4
    if ( ( $array[$i] % 4 ) == 0 ) {
        splice @array, $i + 1, 0, "insert";
    }

    # Remove multiples of 5
    if ( ( $array[$i] % 5 ) == 0 ) {
        splice @array, $i, 1;
    }
}

use Data::Dump;
dd @array;

输出:

(
  1 .. 4,
  "insert",
  6,
  7,
  8,
  "insert",
  9,
  11,
  12,
  "insert",
  13,
  14,
  16,
  "insert",
  17,
  18,
  19,
  "insert",
)

或者,如果你想转换一个数组,也可以像这样使用map

my @newarray = map {
    (   ( ($_) x !!( $_ % 5 ) ),         # Remove multiples of 5
        ( ('insert') x !( $_ % 4 ) ),    # Insert After multiples of 4
        )
} ( 1 .. 20 );

use Data::Dump;
dd @newarray;

【讨论】:

    【解决方案2】:

    您可以分配给现有元素,但不应添加或删除它们。所以没有移位、取消移位、弹出、推送或拼接。 perlsyn:

    如果 LIST 的任何部分是一个数组,如果你在循环体中添加或删除元素,foreach 将变得非常混乱,例如使用 splice。所以不要那样做。

    如果您使用each 迭代哈希,则还应避免添加或删除元素,除非明确允许您删除当前元素。 each:

    如果您在迭代时添加或删除哈希的元素,对迭代器的影响是未指定的;例如,条目可能会被跳过或重复——所以不要这样做。例外:删除each()最近返回的项目总是安全的,所以下面的代码可以正常工作:

    但正如它所说,可能发生的最坏情况是条目被跳过或重复;另一方面,修改您正在循环的数组可能会导致段错误。

    【讨论】:

    • 我认为在一开始就改变数组的元素不是最合乎逻辑的,但使用最后一个元素听起来更自然——它甚至可以工作。不过我明白你的意思。谢谢。
    • 我找不到有关仅将标量作为 LIST 元素的数组上的操作的任何信息。你认为同样的规则适用吗?
    • 不,同样的规则不适用;不知道你所说的“玩”是什么意思。
    • 不知道段错误是否可能,但死亡是可能的。 perl -E'@a=qw( a b c ); for ((),@a) { @a=(); say } say "ok"'
    猜你喜欢
    • 1970-01-01
    • 2011-04-11
    • 2021-12-06
    • 2013-12-11
    • 1970-01-01
    • 1970-01-01
    • 2021-06-29
    • 1970-01-01
    • 2015-11-21
    相关资源
    最近更新 更多