2017-02-21 90 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; 
 
    }, []); 
 
}