Reputation: 277
I am working on formatting a set of data into one array to use for a table. I have a data set like this
data = [{
hello: 'world',
children: [{
foo: 'bar'
}]
}]
I am looking to get this data into one array while marking all of the parent nodes with a parent: true
bool. So I can throw it all into a table but still have a differentiating factor between a parent and child. I know I can just loop twice for the table but I am doing this for reusability purposes. I have a working block of code below.
formattedData (data) {
const formattedData = []
data.map(dataPoint => {
let obj = dataPoint
obj['parent'] = true
formattedData.push(dataPoint)
if (dataPoint.children) {
dataPoint.children.map(c => {
formattedData.push(c)
})
}
})
return formattedData
}
Resulting data looks like this:
data = [{
hello: 'world',
parent: true
}, {
foo: 'bar'
}]
Just checking to see if there is a better/more efficient/prettier way to do this (or if the way I did it is how it should be done). Thanks in advance!
Upvotes: 0
Views: 148
Reputation: 18525
You could do this with a single Array.reduce
, Object.assign
and some ES6 destructuring:
const data = [{ hello: 'world', children: [{ foo: 'bar' }], }, { hello: 'world2' }]
const result = data.reduce((r, {children, ...other}) => {
if(children){
r.push(Object.assign({}, other, {parent: true}))
r.push(...children)
} else r.push(Object.assign({}, other))
return r
}, [])
console.log(result)
If however you have further children
levels then you would have to use a recursive
approach but based on the input data that does not seem to be the case.
You can also shorten if further if you are not concerned about readability
:
const data = [{ hello: 'world', children: [{ foo: 'bar' }], }, { hello: 'world2' }]
const result = data.reduce((r, {children, ...other}) => {
r.push(Object.assign({}, other, children ? {parent: true} : {}))
children ? r.push(...children) : null
return r
}, [])
console.log(result)
Upvotes: 1
Reputation: 225105
If you meant to copy the object with let obj = dataPoint
to not mutate the argument passed to the function and the object is a simple Object
, you can use object spread to copy it and add a property
Array.prototype.flatMap
exists now (and can be made backwards-compatible with shims like everything else)
Why is it a class method if it doesn’t use this
?
const getFormattedData = data =>
data.flatMap(dataPoint => [
{...dataPoint, parent: true},
...dataPoint.children || [],
])
Or, if you also wanted to remove the children
property:
const getFormattedData = data =>
data.flatMap(({children, ...dataPoint}) => [
{...dataPoint, parent: true},
...children || [],
])
Upvotes: 2