React.js中二维数组被意外覆盖问题求助
数独生成函数中grid与puzzle同步修改的问题解决
问题核心是浅拷贝导致的引用共享,和主应用文件无关,就是你复制数组的方式不对。
原因分析
JavaScript里的数组属于引用类型,你用grid.slice()做的是浅拷贝:它只会复制外层数组的结构,但数组里的每个子数组(数独的每一行)仍然是原grid中子数组的引用。这就意味着,当你修改puzzle里的子数组元素(比如设为空字符串)时,实际上修改的是和grid共享的同一个数组元素,所以grid也会跟着变成挖空后的样子。
解决方案
把浅拷贝改成深拷贝,确保puzzle和grid彻底断开引用,有两种简单的实现方式:
方法1:用map+slice复制每一行
替换原代码中的const puzzle = grid.slice();为:
const puzzle = grid.map(row => row.slice());
map会遍历原数组的每一行,row.slice()复制每一行的元素,生成全新的二维数组,和原grid完全独立。
方法2:JSON序列化反序列化(适合纯数据结构)
如果数独网格里只有数字和字符串,也可以用这种方式:
const puzzle = JSON.parse(JSON.stringify(grid));
通过把数组转成JSON字符串再解析,生成一个完全独立的新数组。
修改后的函数示例
修改拷贝逻辑后,你的函数就能正确返回独立的完整网格和挖空后的谜题了:
export function generateSudokuTable(difficulty){ let grid = [[7,2,6,3,5,9,4,1,8], [4,5,8,1,6,7,2,3,9], [9,1,3,8,2,4,7,6,5], [1,6,2,9,7,5,3,8,4], [3,9,4,2,8,6,1,5,7], [8,7,5,4,1,3,9,2,6], [5,3,7,6,4,1,8,9,2], [6,8,9,7,3,2,5,4,1], [2,4,1,5,9,8,6,7,3]]; // 难度对应的挖空数量逻辑不变 let removedValues = 0; if(difficulty === "Beginner"){ removedValues = 18; } else if(difficulty === "Easy"){ removedValues = 27; } else if(difficulty === "Normal"){ removedValues = 36; } else if(difficulty === "Hard"){ removedValues = 45; } else if(difficulty === "Expert"){ removedValues = 54; } else{ removedValues = 81; } // 改用深拷贝生成puzzle const puzzle = grid.map(row => row.slice()); for(let hidden = 0; hidden < removedValues; hidden++){ let isRemoved = false; while(isRemoved === false){ let randomIndex = Math.floor(Math.random() * 81); if(puzzle[Math.floor(randomIndex/9)][randomIndex%9] !== ""){ puzzle[Math.floor(randomIndex/9)][randomIndex%9] = ""; isRemoved = true; } } } return [grid, puzzle]; }
现在你再打印grid,就能看到它始终保持完整的数独数据,而puzzle是挖空后的版本。
内容的提问来源于stack exchange,提问作者Tanner2020
相关产品推荐
相关产品推荐

