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.
Advertisement
Answer
Ideally a solution would require something to tell how far down to start classing the object as been a full object, a simple solution is just to pass the level you want. If you don’t want to pass the level, you could do a check and if none of the properties have array’s, then you would class this as a complete record, but of course that logic is something you would need to confirm.
If you want a generic version that works with multiple levels were you pass the level & using recursion you could do something like this ->
const a=[{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}]}]; function flattern(a, lvl) { const r = []; function flat(a, l, o) { for (const aa of a) { o = {...o}; for (const [k, v] of Object.entries(aa)) { if (Array.isArray(v) && l < lvl) flat(v, l + 1, o); else o[k] = v; } if (l === lvl) r.push(o); } } flat(a, 1); return r; } console.log(flattern(a, 2)); //console.log(flattern(a, 1));