创建三维维度数组
Create 3D dimensional array
在Javascript中,我没有看到任何教程清楚地解释如何创建
MyItems[Row][Index][categories]
因此
MyItems[0][0][0]=1
MyItems[1][0][0]='stock'
MyItems[5][1][0]='pending'
我的用例是每个索引将包含不同的值,即整数或字符串。
在访问没有价值的 MyItems[0][1][0] 时避免出错的最佳方法是什么?
因为 JS 没有实际的多维数组,而只是有嵌套数组,不一定形成矩形结构,所以你需要先检查每个嵌套数组。一个简单的"真实"测试就可以了。
if (myItems[0] && myItems[0][0])
myItems[0][0].push(1);
如果你想创建不存在的数组,那么你可以这样做:
if (!myItems[0])
myItems[0] = [];
if (!myItems[0][0])
myItems[0][0] = [];
myItems[0][0].push(1);
当然,这假设第一级和第二级应该始终是数组,只有第三级才能保存实际值。如果不是这种情况,则需要对其进行调整。
此外,一个函数将是摆脱重复的好主意。
function addNested(outer, idx1, idx2, idx3, value) {
if (!outer[idx1])
outer[idx1] = [];
if (!outer[idx1][idx2])
outer[idx1][idx2] = [];
outer[idx1][idx2][idx3] = value;
}
addNested(myItems, 1, 0, 0, 'stock');
这就是您制作 3D 数组的方式,但我建议不要在数组中混合数据类型,这不是一种常见或标准的做法。
// just filler stuff, ignore the body of this function
function getStringOrNumber(row, col, cat) {
var thing = row * cols * cats + col * cats + cat;
return Math.random() < .5 ? thing : thing.toString();
}
// something to deal with each value
function doSomething(value) {
switch (typeof value) {
case 'string':
// logic for string type
break;
case 'number':
// logic for number type
break;
default:
// unexpected?
break;
}
}
// here's how you make your 3D array
var rows = 10,
cols = 10,
cats = 10,
array3d = new Array(rows),
i, j, k;
for (i = 0; i < rows; i++) {
array3d[i] = new Array(cols);
for (j = 0; j < cols; j++) {
array3d[i][j] = new Array(cats);
for (k = 0; k < cats; k++) {
array3d[i][j][k] = getStringOrNumber(i, j, k);
doSomething(array3d[i][j][k]);
}
}
}
如果要检查 3d 数组上是否存在索引,请尝试如下函数:
function setValue(array3d, row, col, cat, value) {
if (array3d[row] && array3d[row][col] && array3d[row][col][cat]) {
array3d[row][col][cat] = value;
} else {
throw new RangeError("Indices out of range");
}
}
如果您在访问任何数组之前以广度优先模式在每个索引处分配每个数组,那么这将无需任何特殊处理即可工作。
但是,正如您正确识别的那样,如果您希望能够访问可能尚未分配的索引,这将不起作用。
实际上,更具体地说,您可以尝试读取数组长度之外的索引,在这种情况下,您将获得undefined
。问题是,如果第一个或第二个深度undefined
,则尝试为该undefined
值编制索引将失败。
因此,若要防止此错误,必须防止未定义的第一深度或第二深度索引。
执行此操作的最佳方法是编写一个类,该类提供自动处理特殊处理要求的 getter 和 setter。下面是使用原型模式定义的此类的示例:
(function() {
var Array3D = function() {
this.data = [];
};
Array3D.prototype.get = function(r,c,z) {
if (this.data.length <= r) return undefined;
if (this.data[r].length <= c) return undefined;
return this.data[r][c][z];
};
Array3D.prototype.set = function(r,c,z,v) {
if (this.data.length <= r) this.data[r] = [];
if (this.data[r].length <= c) this.data[r][c] = [];
this.data[r][c][z] = v;
return this;
};
window.Array3D = Array3D;
})();
var a = new Array3D();
alert(a.get(0,0,0)); // undefined, no error
a.set(0,0,0,'x');
alert(a.get(0,0,0)); // 'x'
a.set(234,1234,342,'y');
alert(a.get(234,1234,342)); // 'y'
alert(a.get(0,1,0)); // undefined, no error
alert(a.get(12341234,243787,234234)); // undefined, no error
由于这与我的另一个答案完全不同,我认为建议使用嵌套稀疏数组的另一种方法会很有帮助,该方法可以使用关联数组或对象来实现。试试这个:
// N-dimensional array
function ArrayND() {
// nothing to do here, seriously
}
ArrayND.prototype.setValue = function (value) {
var indices = arguments,
nest = this,
index, i;
// note the range of values since the last recursion is being set to a value
for (i = 1; i < indices.length - 2; i++) {
index = indices[i];
if (nest[index] instanceof ArrayND) {
nest = nest[index];
} else if (typeof nest[index] === "undefined") {
// recursive functionality!
nest = nest[index] = new ArrayND();
} else {
// we don't want to get rid of this value by accident!
return false;
}
}
// now "nest" is equal to the ArrayND you want to set the value inside of
index = indices[i];
nest[index] = value;
// we set the value successfully!
return true;
}
ArrayND.prototype.getValue = function () {
var indices = arguments,
nest = this,
index, i;
// note the range because we're getting the last value
for (i = 0; i < indices.length; i++) {
index = indices[i];
// for last recursion, just has to exist, not be ArrayND
if (nest[index]) {
nest = nest[index];
} else {
// nothing is defined where you're trying to access
return undefined;
}
}
return nest;
}
var arrayND = new ArrayND();
arrayND.setValue(1, 0, 0, 0);
arrayND.setValue("stock", 1, 0, 0);
arrayND.setValue("pending", 5, 1, 0);
// you can treat it like a normal 3D array if you want
console.log(arrayND[0][0][0]); // 1
console.log(arrayND[1][0][0]); // "stock"
console.log(arrayND[5][1][0]); // "pending"
// or use a nicer way to get the values
console.log(arrayND.getValue(1, 0, 0)); // "stock"
// phew, no errors!
console.log(arrayND.getValue(3, 1, 0)); // undefined
// some awesome recursive functionality!
console.log(arrayND.getValue(5).getValue(1).getValue(0)); // "pending"
相关文章:
- 将数据附加到关联数组或维度数组
- 如何用javascript创建三维数组我想把数据插入数组中,这有助于我的代码
- Javascript 三维数组,得到错误
- 二维对象/将数组关联到三维对象Javascript中
- 来自 Javascript 中二维数组的三维数组
- JavaScript 中三维数组的范围
- JavaScript:将三维数组连接到二维数组中,将值包装在html标记中
- Javascript数组多维使用拆分为一个新的数组
- Javascript数组多维推入
- angularjs中用于三维数组的ngModel
- javascript中的三维数组
- Javascript中的三维数组
- 查找javascript数组的维数
- 生成三维动态数组在jquery
- 如何Post数组多维角js
- 创建javascript多维数组(三维)与一些规则
- 我只能在二维数组中添加三个元素,而不是四个
- Javascript三维数组与对象文字
- Javascript数组多维推送
- 我想在javascript中对三维数组进行排序