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);