我一直在网上阅读,一些地方说这是不可能的,一些地方说这是可能的,然后给出一个例子,另一些地方反驳这个例子,等等。
如何在JavaScript中声明一个2维数组?(假设这是可能的) 我如何访问它的成员?(myArray[0][1] or myArray[0,1]?)
我一直在网上阅读,一些地方说这是不可能的,一些地方说这是可能的,然后给出一个例子,另一些地方反驳这个例子,等等。
如何在JavaScript中声明一个2维数组?(假设这是可能的) 我如何访问它的成员?(myArray[0][1] or myArray[0,1]?)
当前回答
在一些注释中提到了这一点,但是使用array .fill()将有助于构造一个2-d数组:
function create2dArr(x,y) {
var arr = [];
for(var i = 0; i < y; i++) {
arr.push(Array(x).fill(0));
}
return arr;
}
这将在返回的数组中生成一个长度为x, y的数组。
其他回答
实际上呢?是的。你可以创建一个数组的数组,作为一个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指出的那样。
需要注意的是,您可以将数组嵌套到另一个数组中,从而创建“多维”数组。
我不喜欢使用.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}`);
值得一提的是,在这一点上,创建一个全新的结构将是一个更好的实践,但这很有趣。
创建一个非稀疏的“2D”数组(x,y),所有的索引都是可寻址的,并且值设置为空:
let 2Darray = new Array(x).fill(null).map(item =>(new Array(y).fill(null)))
“3D”数组(x,y,z)
let 3Darray = new Array(x).fill(null).map(item=>(new Array(y).fill(null)).map(item=>Array(z).fill(null)))
关于这个问题的变化和更正已经在评论中提到,并在不同的地方回应了这个问题,但不是一个实际的答案,所以我在这里添加了它。
应该注意的是(类似于大多数其他答案),这有O(x*y)时间复杂度,所以它可能不适合非常大的数组。
我的方法与@Bineesh的答案非常相似,但采用了更普遍的方法。
你可以这样声明双数组:
var myDoubleArray = [[]];
并以以下方式存储和访问内容:
var testArray1 = [9,8]
var testArray2 = [3,5,7,9,10]
var testArray3 = {"test":123}
var index = 0;
myDoubleArray[index++] = testArray1;
myDoubleArray[index++] = testArray2;
myDoubleArray[index++] = testArray3;
console.log(myDoubleArray[0],myDoubleArray[1][3], myDoubleArray[2]['test'],)
这将打印预期的输出
[ 9, 8 ] 9 123