从嵌套的Javascript对象中提取和合并数组

时间:2017-02-21 19:29:23

标签: javascript arrays object extract

我有一个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);

有没有更好的方法来提取子数组项并合并为一个?

2 个答案:

答案 0 :(得分: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; }

答案 1 :(得分: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;
  }, []);
}