我有一个javascript数组,它定义了这样的无限树。
z=['~GROUPHEAD 0~',
'Intro',
'Summary',
['~GROUPHEAD 1~',
'Do this',
['~GROUPHEAD 2~',
'Task 1',
'Task 2'
]
]
]
现在
z[0]='~GROUPHEAD 0~';
z[1]='Intro';
z[2]='Summary';
z[3][0]='~GROUPHEAD 1~';
z[3][1]='Do this';
z[3][2][0]='~GROUPHEAD 2~';
z[3][2][1]='Task 1';
z[3][2][2]='Task 2';
z...[0] is a Header
我想发送一个数字322 or 3.2.2 or [3][2][2]
来选择“任务2”(即z[3][2][2]
)
谁能帮忙;还有更好的方法吗?
我需要称之为100次
答案 0 :(得分:3)
以下是一种方式:http://jsbin.com/uvenus(点击右上方的 jsbin.com 中的编辑进行播放)。这是代码:
Array.prototype.pick = function(num) {
var levels = num.split('.');
var out = this;
for (var i=0;i<levels.length;i++) {
out = out[parseInt(levels[i])];
}
return out;
};
// usage
myArray.pick('3.2.2');
因此,我们在名为pick
的Array实例上创建一个新方法,该方法接受一个字符串(3.2.2对JS不是一个字符串以外的任何意义)。我们将它分成点,然后遍历生成的数字数组,将每个数字作为索引应用于原始数组(并且首先将索引转换为带parseInt()
的整数,尽管JS会自动为您进行类型转换如果你把它遗漏了。)
如果你想让它变得更加万无一失,它应该有一些错误检查,你传入的字符串只包含有效的索引和类似的东西,但这应该让你开始! :)
答案 1 :(得分:2)
您可以拆分数字并递归查找:
var path = '3.2.2',
root = z;
var item = (function walk( root, path ){
root = root[ path.shift() ];
return path.length ? walk( root, path ) : root;
})( root, path.split('.') );
或者您可以执行以下操作:
var path = '3.2.2'
, item = eval('z[' + path.replace(/[^\d\.]/g, '').split('.').join('][') + ']');
以上一行:
如果有人通过无效路径,您应该将其包装在try/catch
中。
答案 2 :(得分:2)
不使用不检查无效路径的eval
的解决方案:
var z = ['~GROUPHEAD 0~',
'Intro',
'Summary',
['~GROUPHEAD 1~',
'Do this',
['~GROUPHEAD 2~',
'Task 1',
'Task 2'
]
]
];
function accessArray(arr, index) {
var parts = index.split(".");
var a = arr;
for(var i = 0; i < parts.length; i++)
a = a[parts[i]];
return a;
}
alert(accessArray(z, "3.2.2"));
答案 3 :(得分:1)
function selectFromArray(ar, index)
{
//get array from indexes
var index_ar = index.split('.');
if(index_ar.length > 1)
{
//set new index value
var indx = "";
//append new index value
for(var i = 1; i < index_ar.length; i++)
{
if(indx.length > 0)
indx += '.';
indx += index_ar[i];
}
//call method again with new index
return selectFromArray(ar[intParse(index_ar[0])], indx);
}
//return value
return ar[intParse(index_ar[0])];
}
我希望我的评论能够描述这种方法的功能,但它可以解决这个问题
所以你可以像
一样调用它selectFromArray(your_array, '3.4.3.2.1.2.3.2.2');
如果索引越界,它将失败:)
答案 4 :(得分:1)
这是一种以面向对象的方式做同样的事情。
MyCompanyGroup = function(name, description, task, parent, child) {
if (arguments.length == 0) return;
this._name = name;
this._description = description;
this._parent = parent;
this._child = child;
}
MyCompanyGroup.prototype.toString =
function() {
return "MyCompanyGroup";
}
var z = new MYCompanyGroup("~GROUPHEAD0~", "Intro", "Summary", this, this);
现在,您可以使用父子关系向上和向下导航层次结构 您还可以将所有这些对象存储在数组中或hashmap中以便直接访问。
如果您有不确定数量的字段,您始终可以在MyCompanyGroup中嵌入一个名称 - 值对数组
这种面向对象方法有两个主要优点
答案 5 :(得分:0)
非常不切实际但非常有趣:P
var num = 322;
if (num < 10)
meh = z[num];
else if (num < 100)
meh = z[Math.floor(num/10)][Math.floor(num % 10)];
else
meh = z[Math.floor(num/100)][Math.floor(num/10 % 10)][Math.floor(num % 10)];
meh // results in "Task 2"