我一直在网上阅读,一些地方说这是不可能的,一些地方说这是可能的,然后给出一个例子,另一些地方反驳这个例子,等等。

如何在JavaScript中声明一个2维数组?(假设这是可能的) 我如何访问它的成员?(myArray[0][1] or myArray[0,1]?)


当前回答

递归函数创建多维数组:

var makeArray = function (dims, arr) {          
    if (dims[1] === undefined) {
        return new Array(dims[0]);
    }

    arr = new Array(dims[0]);

    for (var i=0; i<dims[0]; i++) {
        arr[i] = new Array(dims[1]);
        arr[i] = makeArray(dims.slice(1), arr[i]);
    }

    return arr;
}

构建一个2x3x4x2的4D-Array:

var array = makeArray([2, 3, 4, 2]);    

其他回答

实际上呢?是的。你可以创建一个数组的数组,作为一个2D数组,因为每个项目本身就是一个数组: Let items = [ (1、2), (3、4), (5、6) ]; console.log(项目[0][0]);/ / 1 console.log(项目[0][1]);/ / 2 console.log(项目[1][0]);/ / 3 console.log(项目[1][1]);/ / 4 console.log(项目);

但从技术上讲,这只是一个数组的数组,而不是一个“真正的”2D数组,正如I. J. Kennedy指出的那样。

需要注意的是,您可以将数组嵌套到另一个数组中,从而创建“多维”数组。

Javascript只有一维数组,但正如其他人指出的那样,你可以构建数组的数组。

下面的函数可以用来构造一个固定维度的二维数组:

function Create2DArray(rows) {
  var arr = [];

  for (var i=0;i<rows;i++) {
     arr[i] = [];
  }

  return arr;
}

列的数量其实并不重要,因为在使用数组之前不需要指定数组的大小。

然后你可以调用:

var arr = Create2DArray(100);

arr[50][2] = 5;
arr[70][5] = 7454;
// ...

我不喜欢使用.fill()的ES6解决方案。有些可能可以工作,但为了避免引用复制问题而添加的额外箍使它们不直观。

我建议的ES6方法是对外部数组和内部数组充分利用展开运算符。在我看来,这更容易解释。

[...Array(3)].map(() => [...Array(4)])

如果你需要设置一个初始值,那么你可以在内部数组创建时使用.map()链接:

[...Array(3)].map(() => [...Array(4)].map(() => 0))

最后,一个类型安全的TypeScript util函数:

export const createMultiDimensionalArray = <T>(
  n: number,
  m: number,
  initialVal?: T,
): T[][] => {
  const matrix = [...Array(n)].map(() => [...Array(m)]);
  return initialVal === undefined
    ? matrix
    : matrix.map(r => r.map(() => initialVal));
};

使用它的例子:

const a = createMultiDimensionalArray(1, 2);
a[1][2] = 3;     // Works

const b = createMultiDimensionalArray(2, 3, false);
b[1][2] = true;  // Works
b[1][2] = 3;     // Error: Type '3' is not assignable to type 'boolean'.

这将构造任何维度的数组。

function makeArrayChildren(parent, firstDimension, ...dimensions) {
  for (let i = 0; i < parent.length; i++) {
    parent[i] = new Array(firstDimension);
    if (dimensions.length != 0) {
      makeArrayChildren(parent[i], ...dimensions);
    }
  }
}
function makeArray(firstDimension, ...dimensions) {
  if (firstDimension == undefined) {
    throw Exception("Too few dimensions");
  }
  let topArray = new Array(firstDimension);
  if (dimensions.length != 0) makeArrayChildren(topArray, ...dimensions);
  return topArray;
}

这里还有另外两个我想做的函数,我可以用它作为一个完整性检查:一个用于在多维数组中所有最低级别项上执行的每个函数,一个填充方法。

Array.prototype.dimensionalFill = function (value) {
  for (let i = 0; i < this.length; i++) {
    const elem = this[i];
    if (elem instanceof Array) {
      elem.dimensionalFill(value);
    } else {
      this[i] = value;
    }
  }
};
/*Unlike forEach, this also loops over undefined values. */
Array.prototype.dimensionalForEach = function (callableFunc, thisArg) {
  if (thisArg != undefined) {
    return this.dimensionalForEach(callableFunc.bind(thisArg));
  }
  for (let i = 0; i < this.length; i++) {
    const elem = this[i];
    if (elem instanceof Array) {
      elem.dimensionalForEach(callableFunc);
    } else {
      callableFunc(elem, i, this);
    }
  }
};

这里有一个漂亮的小检查,它使用了所有的特性。所以至少,它不可能完全错误。

let arr = makeArray(10, 10, 5, 4);
arr.dimensionalFill(2);
let sum = 0;
arr.dimensionalForEach((elem) => {
  sum += elem;
});
console.log(`sum: ${sum} === ${10 * 10 * 5 * 4 * 2}`);

值得一提的是,在这一点上,创建一个全新的结构将是一个更好的实践,但这很有趣。

下面的例子定义了一个名为activities的二维数组:

    let activities = [
        ['Work', 9],
        ['Eat', 1],
        ['Commute', 2],
        ['Play Game', 1],
        ['Sleep', 7]
    ];

在活动数组中,第一个维度表示活动,第二个维度显示每个活动每天花费的小时数。

要在控制台中显示活动数组,可以使用console.table()方法,如下所示:

console.table(activities);

输出如下所示:

┌─────────┬─────────────┬───┐ │(index)│0│1│ ├─────────┼─────────────┼───┤ │0│’Work’│9│ │1│’Eat’│1│ │2│’Commute’│2│ │3│’Play Game’│1│ │4│’Sleep’│7│ └─────────┴─────────────┴───┘

注意,(index)列用于表示内部数组的索引。

要访问多维数组的元素,首先使用方括号访问返回内部数组的外部数组的元素;然后使用另一个方括号访问内部数组的元素。

下面的例子返回上面activity数组中第一个内部数组的第二个元素:

console.log(activities[0][1]); // 9

向JavaScript多维数组中添加元素

您可以使用数组方法,如push()和splice()来操作多维数组的元素。

例如,要在多维数组的末尾添加一个新元素,可以使用push()方法,如下所示:

activities.push(['Study',2]);

┌─────────┬─────────────┬───┐ │(index)│0│1│ ├─────────┼─────────────┼───┤ │0│’Work’│9│ │1│’Eat’│1│ │2│’Commute’│2│ │3│’Play Game’│1│ │4│’Sleep’│7│ │5│’Study’│2│ └─────────┴─────────────┴───┘

要在数组中间插入一个元素,可以使用splice()方法。下面的代码将一个元素插入到activities数组的第二个位置:

activities.splice(1, 0, ['Programming', 2]);

┌─────────┬───────────────┬───┐ │(index)│0│1│ ├─────────┼───────────────┼───┤ │0│’Work’│9│ │1│’Programming’│2│ │2│’Eat’│1│ │3│’Commute’│2│ │4│’Play Game’│1│ │5│’Sleep’│7│ │6│’Study’│2│ └─────────┴───────────────┴───┘

这个示例计算在每个活动上花费的时间的百分比,并将该百分比附加到内部数组。

activities.forEach(activity => {
    let percentage = ((activity[1] / 24) * 100).toFixed();
    activity[2] = percentage + '%';
});

┌─────────┬───────────────┬───┬───────┐ │(index)│0│1│2│ ├─────────┼───────────────┼───┼───────┤ │0│’Work’│9│’38%’│ │1│’Programming’│2│’8%’│ │2│’Eat’│1│’4%’│ │3│’Commute’│2│’8%’│ │4│’Play Game’│1│’4%’│ │5│’Sleep’│7│’29%’│ │6│’Study’│2│’8%’│ └─────────┴───────────────┴───┴───────┘

从JavaScript多维数组中删除元素

要从数组中删除一个元素,可以使用pop()或splice()方法。

例如,下面的语句删除了activities数组的最后一个元素:

activities.pop();

┌─────────┬───────────────┬───┬───────┐ │(index)│0│1│2│ ├─────────┼───────────────┼───┼───────┤ │0│’Work’│9│’38%’│ │1│’Programming’│2│’8%’│ │2│’Eat’│1│’4%’│ │3│’Commute’│2│’8%’│ │4│’Play Game’│1│’4%’│ │5│’Sleep’│7│’29%’│ └─────────┴───────────────┴───┴───────┘

类似地,可以使用pop()方法从多维数组的内部数组中删除元素。下面的示例从活动数组的内部数组中删除百分比元素。

activities.forEach((activity) => {
    activity.pop(2);
});

┌─────────┬───────────────┬───┐ │(index)│0│1│ ├─────────┼───────────────┼───┤ │0│’Work’│9│ │1│’Programming’│2│ │2│’Eat’│1│ │3│’Commute’│2│ │4│’Play Game’│1│ │5│’Sleep’│7│ └─────────┴───────────────┴───┘

遍历JavaScript多维数组的元素

要迭代多维数组,可以使用嵌套for循环,如下例所示。

// loop the outer array

for (let i = 0; i < activities.length; i++) {
    // get the size of the inner array
    var innerArrayLength = activities[i].length;
    // loop the inner array
    for (let j = 0; j < innerArrayLength; j++) {
        console.log('[' + i + ',' + j + '] = ' + activities[i][j]);
    }
}

第一个循环遍历外部数组的元素,嵌套循环遍历内部数组的元素。

脚本在控制台中输出如下:

[0,0] =功 [0,1] = 9 [1,0] =吃 [1,1] = 1 [2,0] =通勤 [2,1] = 2 [3,0] =玩游戏 [3,1] = 1 [4,0] =睡眠 [4,1] = 7 [5,0] =学习 [5,1] = 2

或者你可以使用forEach()方法两次:

activities.forEach((activity) => {
    activity.forEach((data) => {
        console.log(data);
    });
});

工作 9 吃 1 上下班 2 玩游戏 1 睡眠 7 研究 2