在循环时修改数组是否安全

Is it safe to modify an array while looping it?

本文关键字:是否 安全 数组 修改 循环      更新时间:2023-09-26

循环时修改数组是否安全,例如推送元素?

我使用下划线每种方法

我建议避免each,除非你绝对需要对集合中的每个项目造成副作用(触发事件,打印结果等)。对于简单地修改您的收藏,有更好的方法。

如果每个添加的元素只是单个输入元素的结果,则典型的功能模式是flatmap数组,可以认为分为两个步骤:

  1. 使用 map 应用一个函数,该函数为每个元素生成一个数组作为结果。总体结果将是一个数组数组。
  2. 在该数组数组上使用flatten来获取一维数组。

使用下划线或短划线:

var origArray = [1, 2, 3, 4];
var duplicateIf3 = function (val) { return val === 3 ? [val, val] : val; };
_.flatten(origArray.map(duplicateIf3));
// -> [1, 2, 3, 3, 4]

(在类型化 FP 中,该函数必须为非 3 的值返回 [val],但flatten不在乎 - 它会展平你给它的任何内容到一个维度。

如果新元素依赖于它之前的所有元素,您可能会改用reducefold,将空数组作为初始值。

var origArray = [1, 2, 3, 4];
origArray.reduce(function (acc, val) { return acc.concat(acc).concat(val); }, []);
// -> [1, 1, 2, 1, 1, 2, 3, 1, 1, 2, 1, 1, 2, 3, 4]

(抱歉,我想不出一个实际的例子,但为了说明目的,这里每一步都以非常简单的方式使用之前所有步骤的完整输出,您可以从原始数组的每个值中看到发生了什么。另请注意,如果您不想使用下划线/lodash,您可以从reduce制作自己的flatten

reduceflatmap更通用,但这两种方法都能够将数组转换为更大的数组,而该数组在某种程度上取决于第一个数组。

如果你有兴趣了解更多,我强烈建议你看看Reg Braithwaite的免费(在线)Javascript Allongé。

我不确定你所说的安全是什么意思,但你必须有一个很好的理由来这样做。我玩了一下,这是我得到的:

_.each(a, function(el) { 
    if (el % 2 == 0) 
        a.push(el + 1); 
    console.log(el); 
});
// logs 1, 2, 3, 4, 5
console.log(a);
// logs [ 1, 2, 3, 4, 5, 3, 5 ]

在这种情况下,除非您想浏览添加的元素,否则不会产生负面影响,但是如果您要更改特定元素,您可能会发现自己处于更棘手的情况:

_.each(a, function(el, index) { 
    a[index + 1] = el - 1;
    if (el % 2 == 0) 
        a.push(el + 1); 
    console.log(el); 
});
// logs 1, 0, -1, -2, -3

在大多数用例中使用_.map会更有意义。