2017-02-21 79 views
2

我有一個JavaScript嵌套的對象,如下所示:提取和合並數組

input_data = { 
    "A1":{ 
     "B1":{ 
      "M1" : [ 
       {"E1":"10","E2":"11"}, 
       {"E1":"20","E2":"21"} 
      ], 
      "M2":[ 
       {"E1":"30","E2":"31"}, 
       {"E1":"40","E2":"41"} 
      ], 
      "M3":[ 
       {"E1":"50","E2":"51"} 
      ] 
     } 
    }, 
    "A2":{ 
     "B2":{ 
      "M1": [ 
       {"E1":"60","E2":"61"}, 
       {"E1":"70","E2":"71"} 
      ], 
      "M2":[ 
       {"E1":"80","E2":"81"}, 
       {"E1":"90","E2":"91"} 
      ] 
     } 
    } 
} 

我需要提取下「M1」,「M2」,「M3」的所有項目成陣列,即,輸出應,如下所示:

output_data = [ 
      {"E1":"10","E2":"11"}, 
      {"E1":"20","E2":"21"}, 
      {"E1":"30","E2":"31"}, 
      {"E1":"40","E2":"41"}, 
      {"E1":"50","E2":"51"}, 
      {"E1":"60","E2":"61"}, 
      {"E1":"70","E2":"71"}, 
      {"E1":"80","E2":"81"}, 
      {"E1":"90","E2":"91"} 
      ]; 

我可以以下面的方式實現這一點:

var output_data = []; 
function traverse(obj) { 
    for (i in obj) { 
     if (!!obj[i] && typeof(obj[i])=="object") { 
      if (Array.isArray(obj[i])){ 
       output_data = output_data.concat([], obj[i]); 
      } 
      traverse(obj[i]); 
     } 
    } 
} 

traverse(input_data); 
console.log(output_data); 

爲Th創建一個更好的方法來提取子數組項併合併成一個?

+0

如果它運行你那麼這屬於在代碼審查。在這種情況下,我會說在函數內移動output_data數組,並在for循環後面的函數底部返回它 –

回答

1

你可以使用嵌套對象的遞歸方法。

function flat(object) { 
 
    function f(o) { 
 
     Object.keys(o).forEach(function (k) { 
 
      if (!o[k]) { 
 
       return; 
 
      } 
 
      if (Array.isArray(o[k])) { 
 
       result = result.concat(o[k]); 
 
       return; 
 
      } 
 
      if (typeof o[k] === 'object') { 
 
       f(o[k]); 
 
      } 
 
     }); 
 
    } 
 
    var result = []; 
 
    f(object); 
 
    return result; 
 
} 
 

 
var input_data = { A1: { B1: { M1: [{ E1: "10", E2: "11" }, { E1: "20", E2: "21" }], M2: [{ E1: "30", E2: "31" }, { E1: "40", E2: "41" }], M3: [{ E1: "50", E2: "51" }] } }, A2: { B2: { M1: [{ E1: "60", E2: "61" }, { E1: "70", E2: "71" }], M2: [{ E1: "80", E2: "81" }, { E1: "90", E2: "91" }] } } }; 
 

 
console.log(flat(input_data));
.as-console-wrapper { max-height: 100% !important; top: 0; }

+0

包裝返回數組是更好的方法。謝謝! – nizantz

0

你可以使用Array.prototype.mapObject.values和扁平化功能:

const input = { 
 
    "A1":{ 
 
     "B1":{ 
 
      "M1" : [ 
 
       {"E1":"10","E2":"11"}, 
 
       {"E1":"20","E2":"21"} 
 
      ], 
 
      "M2":[ 
 
       {"E1":"30","E2":"31"}, 
 
       {"E1":"40","E2":"41"} 
 
      ], 
 
      "M3":[ 
 
       {"E1":"50","E2":"51"} 
 
      ] 
 
     } 
 
    }, 
 
    "A2":{ 
 
     "B2":{ 
 
      "M1": [ 
 
       {"E1":"60","E2":"61"}, 
 
       {"E1":"70","E2":"71"} 
 
      ], 
 
      "M2":[ 
 
       {"E1":"80","E2":"81"}, 
 
       {"E1":"90","E2":"91"} 
 
      ] 
 
     } 
 
    } 
 
}; 
 

 
const values = Object.values.bind(Object); 
 
const output = flattenDeep(values(input).map((inner) => values(inner).map(values))); 
 

 
console.log(output); 
 

 
function flattenDeep(array) { 
 
    return array.reduce((flat, value) => { 
 
    if(Array.isArray(value)) { 
 
     flat.push(...flattenDeep(value)); 
 
    } else { 
 
     flat.push(value); 
 
    } 
 
    return flat; 
 
    }, []); 
 
}