JavaScript 初始化二维数组的陷阱
#TypeScript#JavaScriptPosted ·12138 Views·
问题场景
最近写 TypeScript 时,需要初始化一个二维数组。比如在实现"矩阵置零"算法时,你可能写过类似这样的代码:
const row = 3;
const col = 3;
const matrix_copy: number[][] = new Array(row).fill([]);
这段代码看似合理,但实际上存在一个隐藏的陷阱:所有子数组都是同一个数组的引用!
问题分析
当你使用 new Array(row).fill([])
时:
[]
只被创建一次- 这个空数组的引用被复制到二维数组的每个位置
- 修改
matrix_copy[0][0]
会同时影响matrix_copy[1][0]
,matrix_copy[2][0]
等
我首先实现的暴力算法,也就是O(mn) 的空间复杂度,需要拷贝一个原矩阵。初始化数组都是同一个引用,导致了后续的赋值都错乱,且把 0 都覆盖了,结果最后输出的矩阵中全是 1 😄。
解决方案
方法1:使用 Array.from
const matrix_copy = Array.from({ length: row }, () => []);
Array.from
会为每个元素执行回调函数- 每次执行
() => []
都会创建一个新的空数组
方法2:使用 map
const matrix_copy = new Array(row).fill(null).map(() => []);
- 先用
null
填充数组 - 然后通过
map
为每个元素创建新数组
实际应用
在矩阵算法中,正确的初始化方式应该是:
export const violent = (matrix: number[][]) => {
const row = matrix.length;
const col = matrix[0].length;
// 正确初始化二维数组
const matrix_copy = Array.from({ length: row }, () => new Array(col));
// 复制矩阵
for (let i = 0; i < row; i++) {
for (let j = 0; j < col; j++) {
matrix_copy[i][j] = matrix[i][j];
}
}
// ...其他逻辑
}
总结
在 JavaScript/TypeScript 中初始化二维数组时:
- 避免使用
fill([])
,因为它会共享引用 - 推荐使用
Array.from
或map
方法 - 确保每个子数组都是独立的新实例