Javascript 如何将成员名称展平或合并到一个列表中?
例如,如果我有类似的情况:Javascript 如何将成员名称展平或合并到一个列表中?,javascript,jquery,Javascript,Jquery,例如,如果我有类似的情况: var Constants = { scope:{ namespaceA: { A_X: "TEST_AX" , A_Y: "TEST_AY" }, namespaceN: { N_X: "TEST_NX" , N_Y: "TEST_NY" } } _mapping: [], getMapping: function(){...} } var flattenList = flatten(Constants.scope); //retu
var Constants = {
scope:{
namespaceA: { A_X: "TEST_AX" , A_Y: "TEST_AY" },
namespaceN: { N_X: "TEST_NX" , N_Y: "TEST_NY" }
}
_mapping: [],
getMapping: function(){...}
}
var flattenList = flatten(Constants.scope); //returns ["TEST_AX","TEST_AY","TEST_NX","TEST_NY"]
var anotherWayFlattened = flatten(Constants.scope.namespaceA,Constants.scope.namespaceB); //returns same result as above
编辑:一种方法是通过for each循环迭代作用域,但我在寻找更为简洁的东西
双重编辑:好吧,我只是做了一些如下的事情:
var flattenedList = (function(list){
var flatList = []
$.each(list,function(i,items){
for(var p in items) flatList.push(items[p]);
})
return flatList;
})([Constants.scope.namespaceA,Constants.scope.namespaceB]);
但是我想知道我们是否可以避免传入特定属性,而只传入常量并搜索名称空间列表
[Constants.scope.namespaceA,Constants.scope.namespaceB]
我想知道为什么要在数组中显式传递子对象。为什么不直接传递整个常量.scope
对象
var flattenedList = (function(obj){
var flatList = []
for (var prop in obj) {
var items = obj[prop];
for (var p in items)
flatList.push(items[p]);
}
return flatList;
})(Constants.scope);
从您的评论来看,您似乎想要这样:
var flattenedList = (function(obj, test){
var flatList = []
for (var prop in obj) {
if (!test(prop))
continue;
var items = obj[prop];
for (var p in items)
flatList.push(items[p]);
}
return flatList;
})(Constants, function(name) {
return name.substr(0, 9) == "namespace";
// or maybe
return /^namespace[A-Z]$/.test(name);
});
如果希望递归到任何(非周期!)深度,可以执行以下操作:
function flattenList(list, accumulator){
accumulator = accumulator || [];
for(var p in list){
if(list.hasOwnProperty(p)) {
if(typeof list[p] === "string") {
accumulator.push(list[p]);
} else if(typeof list[p] === "object") { // this is not a reliable test!
flattenList(list[p], accumulator);
}
}
}
return accumulator;
}
这段代码做了许多假设-我们只在对象的末尾有字符串等。或者,如果您事先知道深度,您当前的解决方案可以通过使用concat进行优化:
var flattenedList = (function(list){
return Array.prototype.concat.apply([], list);
})([Constants.scope.namespaceA,Constants.scope.namespaceB]);
这里有一种方法可以实现更深的嵌套。我知道这不是目标的一部分,但我发现这是一个更有趣的问题。:-) 这允许采用以下任一方法:
flatten(Constants.scope);
flatten(Constants.scope.namespaceA, Constants.scope.namespaceN);
您可以传入任意多个单独的参数,也可以传入一个参数。他们都会被搜索到任意深度
对于某些环境,您可能需要填充
数组。prototype
函数map
和reduce
这应该只适用于演示的一个或两个级别,还是适用于任意深度?最多可以使用两个级别Daniel的问题已成为未演示任何工作的默认第一个问题注释。你试过这个吗?有什么进展吗?什么是绊脚石?@每个人:好的,不知道,很酷,我进行了双重编辑是的,很抱歉,在最初的示例中,我从结构Constants.scope.namespaceA
开始,但在我的代码中它更类似于Constants.namespaceA,Constants.namespaceB
。是否有一种方法可以忽略其他属性,例如常量。_映射
,并能够传入整个常量
对象,只拒绝任何不是namespaceA、namespaceB、namespaceN的内容?
flatten(Constants.scope);
flatten(Constants.scope.namespaceA, Constants.scope.namespaceN);