传统的多维数组方法有什么问题?
function ArrayND(size, N, fill) {
if (N < 1) throw new Error('Arrays must have at least one dimension.');
if (size < 1) throw new Error('Arrays must have at least one element.');
var arr = new Array(size);
populate(arr, 1);
function populate(a, depth) {
for (var i = 0; i < size; i++) {
if (depth < N) {
a[i] = new Array(size);
populate(a[i], depth+1);
} else a[i]=fill;
}
}
return arr;
}
这将返回一个访问起来更加直观的多维数组(可以选择填充默认值):
var arr = ArrayND(5, 3, 'hi');
console.log(arr[0][1][2]); // => 'hi'
arr[0][1][3] = 'mom';
更新:由于您的目标是通过提供任意长度的参数来访问多维数组,因此我将使用这种方法:
!function() {
function ArrayND(size, N, fill) {
if (N < 1) throw new Error('Arrays must have at least one dimension.');
if (size < 1) throw new Error('Arrays must have at least one element.');
if (!(this instanceof ArrayND)) return new ArrayND(size, N, fill); // allow this ctor to be called without `new` operator
var arr = this;
arr.length = size;
populate(arr, 1);
function populate(a, depth) {
for (var i = 0; i < size; i++) {
if (depth < N) {
a[i] = new Array(size);
populate(a[i], depth+1);
} else a[i]=fill;
}
}
return arr;
}
var proto = Object.create(Array.prototype); // polyfill necessary for older browsers, see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/create#Polyfill
proto.get = function(indicies) {
var pos = this;
for (var i = 0; i < indicies.length; i++) {
pos = pos[indicies[i]];
}
return pos;
};
proto.set = function(indicies, value) {
var pos = this;
for (var i = 0; i < indicies.length - 1; i++) {
pos = pos[indicies[i]];
}
pos[indicies[indicies.length-1]] = value;
}
ArrayND.prototype = proto;
this.ArrayND = ArrayND; // export to global scope
}();
这为您提供了两全其美:anew ArrayND(s, d)
仍然看起来和行为像一个普通数组,但也为您get
和set
访问器提供了可以在运行时采用任意数量的索引参数——所有这些都无需修改内置的Array
。
var arr = new ArrayND(5, 3, 'hi');
console.log(arr[0][1][2]); // => hi
console.log(arr.get([0,1,2]); // => hi
arr.push([]); // => 6 (the new length)
arr.set([6,0], 'I was added');