2013-02-13 41 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

相關問題