Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flatten nested JavaScript object

I have a nested object and I want to flatten/map it into a single-layered, table-like object.

[{
    a: 1,
    b: 2,
    c: [{
        x: 10,
        y: 20
    }, {
        x: 30,
        y: 40
    }]
}, {
    a: 3,
    b: 4,
    c: [{
        x: 50,
        y: 60
    }, {
        x: 70,
        y: 80
    }]
}]

From that, I want to get something like this:

[{
    a: 1,
    b: 2,
    x: 10,
    y: 20
}, {
    a: 1,
    b: 2,
    x: 30,
    y: 40
}, {
    a: 3,
    b: 4,
    x: 50,
    y: 60
}, {
    a: 3,
    b: 4,
    x: 70,
    y: 80
}]

Sure, I could simply iterate over the object with two for loops and put the result info a separate array, but I wonder, if there is a simpler solution. I already tried to play around with flatMap. It works, if I only want the c portion of my nested object, but I don't know how to map a and b to this object.

As some of you asked for some working code, this should do it (untested):

let result = [];

for (const outer of myObj)
  for (const inner of outer.c)
    result.push({a: outer.a, b: outer.b, x: inner.x, y: inner.y});

The question is, if there is a functional one-liner or even another, better approach. In reality, my object consists of four layers and the nested for loops become messy quite fast.

like image 918
André Reichelt Avatar asked Dec 14 '22 09:12

André Reichelt


1 Answers

You may use flatMap method alongwith map on property 'c':

var input = [{ a: 1, b: 2, c: [{ x: 10, y: 20 }, { x: 30, y: 40 }] }, { a: 3, b: 4, c: [{ x: 50, y: 60 }, { x: 70, y: 80 }] }];

const output = input.flatMap(obj =>
  obj.c.map(arr => ({a: obj.a, b: obj.b, x: arr.x, y: arr.y}))
);

console.log(output);
like image 193
Bilal Siddiqui Avatar answered Dec 20 '22 05:12

Bilal Siddiqui