Reputation: 135
I have a deeply nested object that has the following schema:
const data = {
Car1: {
key: "Car",
value: "1",
child: {
Driver1: {
key: "Driver",
value: "1",
child: {
Trip1: {
key: "Trip",
value: 1,
metrics: { distance: 1, time: 2 }
}
}
},
Driver2: {
key: "Driver",
value: "2",
child: {
Trip1: {
key: "Trip",
value: 1,
metrics: { distance: 3, time: 4 }
},
Trip2: {
key: "Trip",
value: 2,
metrics: { distance: 5, time: 6 }
}
}
}
}
}
}
That I need to flatten into a singular array of objects, with each object in the array having all the properties of its direct child(ren).
Each nested object child
is a Record of objects that have properties key
and value
.
The last object in the nested structure always has a property called metrics
that should be flattened into the object as well.
So the output would look something like:
[
{ Car: 1, Driver: 1, Trip: 1, distance: 1, time: 2 },
{ Car: 1, Driver: 2, Trip: 1, distance: 3, time: 4 },
{ Car: 1, Driver: 2, Trip: 2, distance: 5, time: 6 }
]
I have tried the following code but it only captures one level of depth in the child tree:
private flattenOutput(child: Record<string, OutputChild> = this.output): any[] {
console.log('flattening', Object.keys(child));
return Object.values(child).map((child) => {
return Object.assign(
{},
{ [child.key]: child.value },
...this.flattenOutput(child.child),
child.metrics || {},
);
}, {});
}
Upvotes: 0
Views: 266
Reputation: 22265
I will do that this way :
data =
{ Car1: { key: "Car", value: "1", child:
{ Driver1: { key: "Driver", value: "1", child:
{ Trip1: { key: "Trip", value: 1, metrics: { distance: 1, time: 2} }
} }
, Driver2:
{ key: "Driver", value: "2", child:
{ Trip1: { key: "Trip", value: 1, metrics: { distance: 3, time: 4} }
, Trip2: { key: "Trip", value: 2, metrics: { distance: 5, time: 6} }
} } } } }
let result = []
for (let Car in data )
for (let Driver in data[Car].child)
for (let Trip in data[Car].child[Driver].child)
result.push(
{ Car : data[Car].value
, Driver : data[Car].child[Driver].value
, Trip : data[Car].child[Driver].child[Trip].value
, distance : data[Car].child[Driver].child[Trip].metrics.distance
, time : data[Car].child[Driver].child[Trip].metrics.time
})
console.log( result )
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 0
Reputation: 386540
By having correct nested objects, you could take a recursive approach and collect key/value and return a flat array with wanted objects.
const
collect = (object, temp = {}) => Object
.values(object)
.flatMap(({ key, value, child, metrics }) => child
? collect(child, { ...temp, [key]: value })
: { ...temp, [key]: value , ...metrics }
),
data = { Car1: { key: "Car", value: "1", child: { Driver1: { key: "Driver", value: "1", child: { Trip1: { key: "Trip", value: 1, metrics: { distance: 1, time: 2 } } } }, Driver2: { key: "Driver", value: "2", child: { Trip1: { key: "Trip", value: 1, metrics: { distance: 3, time: 4 } }, Trip2: { key: "Trip", value: 2, metrics: { distance: 5, time: 6 } } } } } } },
result = collect(data);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 3