2

I have a javascript nested object as shown below :

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"}
            ]
        }
    }
}

I need to extract all the items under "M1","M2","M3" into an array, that is , the output should be as shown below:

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"}
            ];

I could achieve this in the following way:

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

Is there a better way of extracting the child array items and merging into one?

1
  • If it runs for you then this belongs on codereview. In which case I'd say move the output_data array inside the function and return it at the bottom of the function after the for loop Commented Feb 21, 2017 at 19:32

2 Answers 2

1

You could use a recursive approach for nested objects.

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; }

Sign up to request clarification or add additional context in comments.

1 Comment

Wrapping the return array is a better approach. Thanks!
0

You could use Array.prototype.map, Object.values and a flatten function:

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;
  }, []);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.