我得到了一些json数据,我有这样的结构:
'modules' : {
'category1' : {
'section1' : {
'page1' : [ 'module1', 'module2' ]
},
'section2' : {
'page1' : [ 'module1' ]
}
},
// and so on
}
我需要获取某些页面的所有模块。
输入参数为category
,section
和page
。
所以我需要获得模块[category] [section] [page]。
但是,如果这样的部分或页面没有模块,那该怎么办呢。
// m = getAllModules();
if ( m.hasOwnProperty(category) ) {
if ( m[category].hasOwnProperty(section) ) {
if (m[category][section].hasOwnProperty(page)) {
concrete = m[category][section][page];
}
}
}
如何优化此脚本?这是很多m []的调用。有更好(更快)的方法吗?
答案 0 :(得分:5)
你可以这样做:
var categories, sections;
if ((categories = modules[categoryName]) && (sections = categories[sectionName])) {
concrete = sections[pageName] || [];
}
else {
concrete = [];
}
您还可以创建更通用的解决方案:
function traverse(source) {
var path = Array.prototype.slice.call(arguments, 1);
var current = source;
for (var i = 0, l = path.length; i < l; ++i) {
current = current[path[i]];
if (!current) break;
}
return current;
}
像这样使用:
concrete = traverse(modules, categoryName, sectionName, pageName) || [];
答案 1 :(得分:2)
嗯,你可以把它变成一个递归函数,虽然这可能会慢一些。但它更容易理解,并且可以重复使用。
function getFromJSON(object, listOfPropertyNames) {
if (listOfPropertyNames.length == 0 || object == undefined) {
return object;
}
var propertyToFind = listOfPropertyNames[0];
if (object.hasOwnProperty(propertyToFind)) {
return getFromJSON(object[propertyToFind], listOfPropertyNames.slice(1));
}
}
concrete = getFromJSON(m, ['category','section','page'])
答案 2 :(得分:1)
考虑使用实用功能:
function grab( val, names ) {
names = names.split( '.' );
while ( val && names.length ) { val = val[ names.shift() ]; }
return val;
}
用法:
grab( m, 'category1.section1.page1' ) // returns [ 'module1', 'module2' ]
grab( m, 'category7.section1.page1' ) // returns undefined