MK
摩柯社区 - 一个极简的技术知识社区
AI 面试

JavaScript多维数组的构建与操作

2021-04-111.5k 阅读

什么是 JavaScript 多维数组

在 JavaScript 中,数组是一种非常重要的数据结构,它允许我们在一个变量中存储多个值。一维数组是最常见的数组形式,例如:

let singleDimArray = [1, 2, 3];

而多维数组则是数组的数组,也就是数组中的元素又是数组。最常见的多维数组是二维数组,它可以看作是一个表格,有行和列。例如,以下是一个简单的二维数组,模拟了一个 3x3 的矩阵:

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

在这个二维数组中,twoDimArray[0][1, 2, 3]twoDimArray[1][4, 5, 6]twoDimArray[2][7, 8, 9]。并且 twoDimArray[0][0]1twoDimArray[1][2]6 等等。

多维数组并不局限于二维,还可以有三维、四维甚至更多维。例如,一个三维数组可以模拟一个立体空间中的数据分布,以下是一个简单的三维数组示例:

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

这里 threeDimArray[0][0][0]1threeDimArray[1][1][1]8

构建 JavaScript 多维数组

直接初始化构建

最直接的构建多维数组的方式就是像上面示例那样,通过在数组字面量中嵌套数组字面量来实现。例如构建一个 4x4 的二维数组表示棋盘:

let chessBoard = [
    ['r', 'n', 'b', 'q', 'k', 'b', 'n', 'r'],
    ['p', 'p', 'p', 'p', 'p', 'p', 'p', 'p'],
    [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '],
    [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '],
    [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '],
    [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '],
    ['P', 'P', 'P', 'P', 'P', 'P', 'P', 'P'],
    ['R', 'N', 'B', 'Q', 'K', 'B', 'N', 'R']
];

这种方式直观且简单,适用于已知数据内容且数据量不大的情况。

使用循环构建

当我们需要构建一个较大规模的多维数组,并且数组元素有一定规律时,使用循环构建会更加方便。例如构建一个 10x10 的二维数组,每个元素是其行列索引的乘积:

let productMatrix = [];
for (let i = 0; i < 10; i++) {
    productMatrix[i] = [];
    for (let j = 0; j < 10; j++) {
        productMatrix[i][j] = i * j;
    }
}

在这段代码中,外层循环控制行数,内层循环控制列数。首先为每一行创建一个空数组,然后在内层循环中填充具体的元素值。

如果要构建三维数组,例如一个 3x3x3 的数组,每个元素是其三个维度索引的和,可以这样写:

let sumCube = [];
for (let i = 0; i < 3; i++) {
    sumCube[i] = [];
    for (let j = 0; j < 3; j++) {
        sumCube[i][j] = [];
        for (let k = 0; k < 3; k++) {
            sumCube[i][j][k] = i + j + k;
        }
    }
}

这里使用了三层循环,分别对应三维数组的三个维度。

使用 Array.from 方法构建

Array.from 方法可以从一个类数组对象或者可迭代对象创建一个新的数组实例。我们可以利用它来构建多维数组。例如构建一个 5x5 的二维数组,元素初始值都为 0:

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

这里外层 Array.from 创建一个长度为 5 的数组,对于每个元素,通过传入的回调函数,再使用内层 Array.from 创建一个长度为 5 且元素都为 0 的数组。这种方式比较简洁,适用于创建有规律的多维数组。

访问 JavaScript 多维数组元素

二维数组元素访问

对于二维数组,访问元素需要使用两个索引,第一个索引表示行,第二个索引表示列。例如对于前面定义的 twoDimArray

let value = twoDimArray[1][2];
console.log(value); // 输出 6

这里 twoDimArray[1] 访问到第二行 [4, 5, 6],然后 [2] 访问到该行的第三个元素 6

三维及以上数组元素访问

三维数组访问需要三个索引,以此类推。对于前面定义的 threeDimArray

let threeDimValue = threeDimArray[1][0][1];
console.log(threeDimValue); // 输出 6

这里 threeDimArray[1] 访问到第二层数组 [[5, 6], [7, 8]][0] 访问到该层数组的第一个子数组 [5, 6],最后 [1] 访问到 [5, 6] 中的第二个元素 6

遍历 JavaScript 多维数组

二维数组遍历

使用 for 循环遍历

最常见的遍历二维数组的方式是使用嵌套的 for 循环。例如遍历前面的 chessBoard 数组并打印每个元素:

for (let i = 0; i < chessBoard.length; i++) {
    for (let j = 0; j < chessBoard[i].length; j++) {
        console.log(chessBoard[i][j]);
    }
}

外层循环遍历行,内层循环遍历列,这样可以依次访问二维数组中的每个元素。

使用 forEach 方法遍历

forEach 方法也可以用于遍历二维数组。例如:

chessBoard.forEach((row, i) => {
    row.forEach((piece, j) => {
        console.log(`在第 ${i} 行,第 ${j} 列的棋子是 ${piece}`);
    });
});

这里外层 forEach 遍历每一行,内层 forEach 遍历每一行中的元素。

三维数组遍历

使用多层 for 循环遍历

对于三维数组,需要使用三层 for 循环来遍历。例如遍历前面定义的 sumCube 数组:

for (let i = 0; i < sumCube.length; i++) {
    for (let j = 0; j < sumCube[i].length; j++) {
        for (let k = 0; k < sumCube[i][j].length; k++) {
            console.log(sumCube[i][j][k]);
        }
    }
}

通过这三层循环,我们可以访问三维数组中的每一个元素。

使用递归方法遍历

对于更高维度的数组,使用递归方法遍历会更加灵活。例如对于一个不确定维度的多维数组,可以这样实现递归遍历:

function recursiveTraverse(arr) {
    arr.forEach((element, index) => {
        if (Array.isArray(element)) {
            recursiveTraverse(element);
        } else {
            console.log(`在位置 ${index} 的元素是 ${element}`);
        }
    });
}
let multiDimArray = [
    [1, 2],
    [
        [3, 4],
        [5, 6]
    ]
];
recursiveTraverse(multiDimArray);

在这个递归函数中,如果元素是数组,则继续递归调用该函数,否则打印元素。

操作 JavaScript 多维数组

修改多维数组元素

修改多维数组元素和访问元素类似,先定位到要修改的元素位置,然后进行赋值。例如修改 twoDimArray 中第二行第三列的元素:

twoDimArray[1][2] = 10;
console.log(twoDimArray);

这样 twoDimArray[1][2] 位置的元素就从 6 变成了 10

向多维数组中添加元素

向二维数组添加行

要向二维数组添加一行,可以使用 push 方法。例如向 twoDimArray 添加一行 [10, 11, 12]

twoDimArray.push([10, 11, 12]);
console.log(twoDimArray);

向二维数组添加列

向二维数组添加列稍微复杂一些,需要遍历每一行并在每一行末尾添加元素。例如向 twoDimArray 的每一行添加一个新元素 0

twoDimArray.forEach(row => row.push(0));
console.log(twoDimArray);

向三维数组添加层

向三维数组添加一层,可以使用 push 方法。例如向 threeDimArray 添加一层 [[9, 10], [11, 12]]

threeDimArray.push([[9, 10], [11, 12]]);
console.log(threeDimArray);

从多维数组中删除元素

从二维数组删除行

从二维数组删除行可以使用 splice 方法。例如删除 twoDimArray 的第二行:

twoDimArray.splice(1, 1);
console.log(twoDimArray);

这里 splice(1, 1) 表示从索引 1 开始删除 1 个元素,也就是第二行。

从二维数组删除列

从二维数组删除列需要遍历每一行并使用 splice 方法删除对应列的元素。例如删除 twoDimArray 每一行的第二个元素:

twoDimArray.forEach(row => row.splice(1, 1));
console.log(twoDimArray);

从三维数组删除层

从三维数组删除层同样可以使用 splice 方法。例如删除 threeDimArray 的第一层:

threeDimArray.splice(0, 1);
console.log(threeDimArray);

多维数组的应用场景

矩阵运算

在数学和计算机图形学中,矩阵运算是非常常见的。二维数组可以很好地表示矩阵。例如矩阵乘法,假设有两个矩阵 AB

let A = [
    [1, 2],
    [3, 4]
];
let B = [
    [5, 6],
    [7, 8]
];
let result = [];
for (let i = 0; i < A.length; i++) {
    result[i] = [];
    for (let j = 0; j < B[0].length; j++) {
        result[i][j] = 0;
        for (let k = 0; k < A[0].length; k++) {
            result[i][j] += A[i][k] * B[k][j];
        }
    }
}
console.log(result);

这段代码实现了两个 2x2 矩阵的乘法,通过多维数组进行矩阵表示和运算。

游戏地图

在游戏开发中,多维数组常用于表示游戏地图。例如一个二维数组可以表示一个平面地图,数组中的每个元素可以表示地图上的不同地形,如草地、山脉、河流等。一个三维数组可以用于表示立体的游戏场景,比如一个多层的迷宫。

let gameMap = [
    ['G', 'G', 'M', 'G'],
    ['G', 'R', 'G', 'G'],
    ['G', 'G', 'G', 'G']
];
// 'G' 表示草地,'M' 表示山脉,'R' 表示河流

通过这样的二维数组,游戏程序可以方便地处理地图的渲染、碰撞检测等逻辑。

数据分析

在数据分析领域,多维数组可以用于存储和处理具有多个维度的数据。例如,在一个销售数据统计中,可能会有年份、月份、地区等多个维度。可以使用三维数组来存储每个月每个地区的销售额:

let salesData = [];
for (let year = 0; year < 3; year++) {
    salesData[year] = [];
    for (let month = 0; month < 12; month++) {
        salesData[year][month] = [];
        for (let region = 0; region < 5; region++) {
            salesData[year][month][region] = Math.floor(Math.random() * 1000);
        }
    }
}

这样的数据结构便于进行各种统计分析,如计算每年的总销售额、每个地区的年度销售额等。

通过以上内容,我们对 JavaScript 多维数组的构建、访问、遍历、操作以及应用场景有了较为深入的了解。在实际编程中,根据具体需求合理使用多维数组可以高效地解决各种复杂问题。