I have an array of objects that has one of the properties("attributes"
) as array of objects.
var products = [
{
"productId": "1",
"attributes": [
{
"variant":"red",
"price": "134.00"
}
]
},
{
"productId": "2",
"attributes": [
{
"variant": "green",
"value": "3400.00"
},
{
"variant": "pink",
"price": "342.00"
}
]
}
]
I want the nested array of objects to be flattened and copied onto parent but the parent object needs to be duplicated for each of the nested object. (Not sure if I have explained it correctly).
The converted array of objects should be:
var transformedProducts = [
{
"productId": "1",
"variant":"red",
"price": "134.00"
},
{
"productId": "2",
"variant": "green",
"value": "3400.00"
},
{
"productId": "2",
"variant": "pink",
"price": "342.00"
}
]
I can map over the outer array and then again map over the inner array, and in the inner most map, construct a new object.
Is there a better or more functional approach to this?
You can use Array.flatMap()
to iterate the objects, and then iterate the attributes
with Array.map()
, and combine with the rest of the object. The Array.flatMap()
would also flatten the array of arrays to a single array.
const fn = arr => arr.flatMap(({ attributes, ...rest }) =>
attributes.map(o => ({
...rest,
...o
}))
)
const products = [{"productId":"1","attributes":[{"variant":"red","price":"134.00"}]},{"productId":"2","attributes":[{"variant":"green","value":"3400.00"},{"variant":"pink","price":"342.00"}]}]
const result = fn(products)
console.log(result)
With Ramda, you can iterate and flatten the array using R.chain
. To get an array of attributes combined with their parents, you can use the R.ap
as combinator of two functions:
const { chain, ap, pipe, prop, applyTo, omit, mergeRight, map } = R
const fn = chain(ap(
pipe(prop('attributes'), applyTo),
pipe(omit(['attributes']), mergeRight, map)
))
const products = [{"productId":"1","attributes":[{"variant":"red","price":"134.00"}]},{"productId":"2","attributes":[{"variant":"green","value":"3400.00"},{"variant":"pink","price":"342.00"}]}]
const result = fn(products)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.28.0/ramda.min.js" integrity="sha512-t0vPcE8ynwIFovsylwUuLPIbdhDj6fav2prN9fEu/VYBupsmrmk9x43Hvnt+Mgn2h5YPSJOk7PMo9zIeGedD1A==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>