前言

刷算法题的时候,遇到一个需求,需要创建一个指定 n x n,指定值为 0 的多维数组,这还不简单,哼~

let n = 5;
let multiArray = Array(n).fill(Array(n).fill(0));

咋一看好像没啥问题,结果最终问题就出在创建数组这!!!

看代码,我修改其中一个元素的值:

multiArray[0][0] = "AlwaysWM";
console.log(multiArray);

输出是啥呢?

javascript 多维数组声明 js创建多维数组_javascript


javascript 多维数组声明 js创建多维数组_数组_02


从结果中可以看出来,外层的3个数组元素指向了同一个数组,所以我改变其中一个内层数组的值,其他数组值也同步修改了,所以想要进行二维数组的初始化,不能这么做!!!

或许是因为数组没有通过 new 出来的原因?修改代码如下:

let n = 5;
let multiArray = new Array(n).fill(new Array(n).fill(0));

结果还是一样的…

我翻阅了 MDN 和一些文档,暂时不知为什么会这样,如果有知道的小伙伴,请在留言区帮忙解答下~

for

尽管这样,我们还是要想办法解决呀,最简单粗暴的方法,就是 for 循环了:

const arr = [], n = 5;
for (let i = 0; i < n; i++) {
  arr[i] = [];
  for (let j = 0; j < n; j++) {
    arr[i][j] = 0;
  }
}

map

既然是循环,当然少不了 map 了~

let n = 5;
const arr = new Array(n).fill(0).map(() => new Array(n).fill(0));

Array.from

我们也可以通过类数组来实现多维数组的创建,

Array.from 能将一个类数组或可迭代对象转换成真实的数组,可以给第二个参数传递一个函数来修改新数组的元素,就像 map 一样,

关于类数组,只要是有 length 属性的对象,就被视为类数组,

let n = 5;
const arr = Array.from({length: n}, () => Array.from({length: n}, () => 0));

优化

上面 for 循环的代码太长,而 map 和 Array.from 的代码不宜阅读,写起来很爽,同事可能就会骂娘了,作为一个优秀的程序员,必须让自己的代码像诗一样~

在 Java 中,我们定义一个二维数组很方便,也很简单明了:

int arr[5][5];

所以,我就想实现一个函数,简单明了地创建与设置多维数组的初值。

Proxy

let root = []
let tile = [root]
// 拦截器
const handers = {
    get(target, key) {
        key = parseInt(key)
        if (key <= 0) {
            try {
                let res = JSON.stringify(root[0])
                res = res.replaceAll('null', Math.abs(key))
                return JSON.parse(res)
            } finally {
                root = []
                tile = [root]
            }
        } else {
            const next = []
            for (const two of tile) {
                for (let i = 0; i < (two.length || 1); i++) {
                    const one = new Array(key)
                    two[i] = one
                    next.push(one)
                }
            }
            tile = next
        }
        return int
    },
}
// 用 proxy 创建 int
const int = new Proxy({}, handers)

至此,我们就可以像 Java 一样,简单明了的定义多维数组了:

const arr = int[10][10][0] // 10*10 初值为 0 的数组