2013-02-13 28 views
-1

例如,如果我有一些像这样:如何将会员名称拼合或组合成一个列表?

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循环遍历范围,但我一直在寻找的东西更高贵?

DOUBLE编辑:确定我刚刚刮起的东西了,像这样:

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

,但不知道如果我们能够避免将在特定的属性,只是通过在常量和搜索命名空间的列表

+0

这是否应该只用一个或两个级别演示或工作到任意深度? – 2013-02-13 19:32:33

+0

达到2级就可以了 – dchhetri 2013-02-13 19:33:20

+0

丹尼尔的问题已成为默认的第一个问题评论,对任何没有表现出任何努力的问题。你试过这个吗?有什么东西接近?什么是绊脚石? – 2013-02-13 19:36:29

回答

1

[Constants.scope.namespaceA,Constants.scope.namespaceB]

我不知道为什么你在阵列中明确地传递子对象。为什么不只是传递整个Constants.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); 
}); 
+0

对此感到抱歉,在最初的例子中,我开始使用结构'Constants.scope.namespaceA',但在我的代码中它更类似于'常量.namespaceA,Constants.namespaceB'。有没有办法忽略其他属性,比如'Constants._mappings',并且能够传入整个Constants对象,只是拒绝任何不是namespaceA,namespaceB,namespaceN? – dchhetri 2013-02-13 19:56:25

1

,如果你想改乘任何(!非周期)的深度,你可以这样做:

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

以下是一种允许更深层嵌套的方法。我知道这不是目标的一部分,但我发现它是一个更有趣的问题。 :-)

var flatten = (function() { 
    var toString = Object.prototype.toString, slice = Array.prototype.slice; 
    var flatten = function(input, output) { 
     var value; 
     output = (toString.call(output) == "[object Array]") ? output : []; 
     for (name in input) {if (input.hasOwnProperty(name)) { 
      value = input[name]; 
      if (toString.call(value) == "[object Object]") { 
       flatten(value, output); 
      } else { 
       output.push(value); 
      } 
     }}; 
     return output; 
    }; 
    var merge = function(first, second) { 
     return first.concat(second); 
    } 

    return function() { 
     return slice.call(arguments).map(flatten).reduce(merge); 
    }; 
}()); 

这使得这两种方法:

flatten(Constants.scope); 
flatten(Constants.scope.namespaceA, Constants.scope.namespaceN); 

您可以通过在许多单独的参数,只要你喜欢,或一个参数。他们都会被搜索到任意的深度。

对于某些环境,您可能需要垫足Array.prototype函数mapreduce

相关问题