【问题标题】:Replicate Array Of Arrays And Modify Same Element Of Each Sub-Array复制数组数组并修改每个子数组的相同元素
【发布时间】:2019-06-11 09:53:53
【问题描述】:

我正在尝试复制一个数组数组,然后修改每个子数组的相同元素。

以下代码用于复制数组的初始数组:

const array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
const n = 2;  // replicate twice
let replicated_arrays = [];
for (let i = 0; i < n; i++) {    
    replicated_arrays.push(array);
}
replicated_arrays = [].concat.apply([], replicated_arrays);  // flatten to make one array of arrays 

然后使用以下代码修改每个数组的第二个元素:

const init = 10;
replicated_arrays.forEach(function(element, index, entireArray) {
    entireArray[index][1] = init + index;
});

想要的输出是:

[[1, 10, 3], [4, 11, 6], [7, 12, 9], [1, 13, 3], [4, 14, 6], [7, 15, 9]]

但是,上面的代码会产生以下结果:

[[1, 13, 3], [4, 14, 6], [7, 15, 9], [1, 13, 3], [4, 14, 6], [7, 15, 9]]

如果手动创建复制数组,则 forEach 会正确更新:

let replicated_arrays = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [1, 2, 3], [4, 5, 6], [7, 8, 9]];

因此,我怀疑它与创建对初始数组的两个实例的引用的 push 方法有关,以便将最终的一组值(13、14 和 15)应用于两个实例。

作为 push 方法的替代方法,我尝试了 map 方法(例如,按照Duplicate an array an arbitrary number of times (javascript)),但它产生了相同的结果。

对于正在发生的事情或如何使其正常工作的任何见解或建议将不胜感激。

【问题讨论】:

    标签: javascript


    【解决方案1】:

    您需要复制内部数组,因为您需要丢失相同的对象引用。

    对于推送,您可以展开数组并稍后省略展平。

    const array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
    const n = 2;  // replicate twice
    let replicated_arrays = [];
    for (let i = 0; i < n; i++) {    
        replicated_arrays.push(...array.map(a => a.slice())); // spread array
    }
    // no need for this! replicated_arrays = [].concat.apply([], replicated_arrays);
    
    const init = 10;
    replicated_arrays.forEach(function(element, index) {
        element[1] = init + index; // access element directly without taking the outer array
    });
    
    console.log(replicated_arrays);

    【讨论】:

    • 在查看我的完整代码时,我发现我尝试(未成功)通过推送副本来破坏引用。但是,这很好用。并且很好地利用了传播。非常感谢。
    【解决方案2】:

    而不是 concat 使用 reduce 方法将保持相同的引用。

    const array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
    const n = 2;  // replicate twice
    let replicated_arrays = [];
    for (let i = 0; i < n; i++) {    
        replicated_arrays.push(array);
    }
    replicated_arrays = replicated_arrays.reduce(function(a, b){
       return a.concat(b);
    }, []);
    
    replicated_arrays.forEach((_ae,i) => {
       _ae[1] = 10 + i;
    })
    console.log(replicated_arrays);
    output: [[1, 10, 3], [4, 11, 6], [7, 12, 9], [1, 13, 3], [4, 14, 6], [7, 15, 9]]
    

    【讨论】:

    • 在 Chrome 和 Firefox 以及 Node.js 函数中运行,我得到了与最初报告的相同的输出。你是如何产生这个输出的?
    猜你喜欢
    • 1970-01-01
    • 2021-05-11
    • 2023-02-15
    • 2013-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-19
    相关资源
    最近更新 更多