猿问

如何使用类似函数的映射创建数组的浅表副本?

如果我有一个 4x4 2d 数组并且想要处理特定列,我可以使用地图获取它并将其设置回来,或者我可以获得它的浅表副本并直接处理原始数组值。


获取/设置方式


// create the original array

let arr = [...Array(4)].map(e => Array(4).fill(0))

console.log(arr)


// get a specific column, e.g. the 3d

let myColumn = arr.map(tile => tile[3])


// change it

myColumn[2] = 1


// set it back

arr.map((line, i) => line[3] = myColumn[i])


console.log("modified array", arr)

现在,我怎样才能用浅拷贝实现同样的事情,即不必重新设置值?


斯蒂芬大帝
浏览 141回答 3
3回答

暮色呼如

你不能制作原始值的“浅拷贝” ——当你arr.map(tile => tile[3])制作一个带有新值的新数组时,所以改变一个不会改变另一个。但是,您可以创建一个对象数组,因为对象的值是它们的引用let grid = [  [{value: 1}, {value: 2}],  [{value: 3}, {value: 4}],];//take a columnlet col2 = grid.map(row => row[1]);//change one valuecol2[1].value = 42;//the original changedconsole.log(grid);如果需要根据列进行频繁的更改,则不需要map(row => row[columnNumber])每次都进行甚至矩阵转置来有效旋转网格。您可以简单地制作两个网格 - 一个代表列,另一个代表行。如果您首先从“普通”网格开始,用对象填充它,然后将其转置,那么您将有效地对同一数据有两个视图:let rows = [  [ {cell: "a1"}, {cell: "a2"}, {cell: "a3"}, {cell: "a4"} ],  [ {cell: "b1"}, {cell: "b2"}, {cell: "b3"}, {cell: "b4"} ],  [ {cell: "c1"}, {cell: "c2"}, {cell: "c3"}, {cell: "c4"} ],  [ {cell: "d1"}, {cell: "d2"}, {cell: "d3"}, {cell: "d4"} ]];//transposelet columns = rows[0].map((col, i) => rows.map(row => row[i]));//show console.log("rows:");console.log(format(rows));console.log("----");console.log("columns:");console.log(format(columns));console.log("----");//take a columnlet col2 = columns[1];//update a valuecol2[2].cell = "XX";//show againconsole.log("after the change");console.log("rows:");console.log(format(rows));console.log("----");console.log("columns:");console.log(format(columns));console.log("----");//helper function to display the grids more compactlyfunction format(arr) {   return arr     .map(arr => arr.map(({cell}) => cell).join())     .join("\n");}

慕无忌1623718

如果你想制作一个浅拷贝,你必须使用一个对象,而不是一个基元。代码可能如下所示:// filling the array:/*...*/.fill({value: 0})// changing the value:myColumn[2].value = 1我不知道你的应用程序对资源有多敏感,但这样你的内存消耗会在一定程度上增加(取决于应用程序)。

动漫人物

// create the original arraylet arr = [...Array(4)].map(e => Array(4).fill(0))console.log(arr)// get copy of arr with changed columnconst cloneSquareAndChangeColumn = (square, colIndex, newValue) => {  return square.map((row, col) => {    return [...row.slice(0, colIndex), newValue, ...row.slice(colIndex + 1)];  });}// test changing last columnconsole.log("cloned and changed arr: \n", cloneSquareAndChangeColumn(arr, 3, 1));
随时随地看视频慕课网APP

相关分类

JavaScript
我要回答