I have a collection that looks similar to this:
[
{
"name": "Item 1",
"id": 200244,
"siblings": []
}, {
"name": "Item 2",
"id": 200134,
"siblings": []
}, {
"name": "Item 3",
"id": 200179,
"siblings": [
{
"name": "Item 3 SubItem 1",
"id": 200146
}
]
}, {
"name": "Item 4",
"id": 200133,
"siblings": []
}, {
"name": "Item 5",
"id": 200135,
"siblings": [
{
"name": "Item 5 SubItem 1",
"id": 200146
}
]
}
]
I’m trying to flatten this so that the child siblings
values are pulled up a level only when they aren’t empty. The end structure would look like this:
[
{
"name": "Item 1",
"id": 200244
}, {
"name": "Item 2",
"id": 200134
}, {
"name": "Item 3",
"id": 200179
}, {
"name": "Item 3 SubItem 1",
"id": 200146
}, {
"name": "Item 4",
"id": 200133
}, {
"name": "Item 5",
"id": 200135
}, {
"name": "Item 5 SubItem 1",
"id": 200146
}
]
Suggestions on where to get started with this? I’ve toyed with Lodash’s flatMap
without success.
Picking flatMap
is the right choice
const data =
...
const flatMap = (f, xs = []) =>
xs.reduce ((acc, x) => acc.concat (f (x)), [])
flatMap (({ siblings = [], ...item }) => [ item, ...siblings ], data)
// [ { name: 'Item 1', id: 200244 }
// , { name: 'Item 2', id: 200134 }
// , { name: 'Item 3', id: 200179 }
// , { name: 'Item 3 SubItem 1', id: 200146 }
// , { name: 'Item 4', id: 200133 }
// , { name: 'Item 5', id: 200135 }
// , { name: 'Item 5 SubItem 1', id: 200146 }
// ]
Using lodash's _.flatMap
is almost identical to our implementation above - only the order of the arguments is switched
const data =
...
const result =
_.flatMap ( data
, ({ siblings = [], ...item }) => [ item, ...siblings ]
)
console.log (result)
// [ { name: 'Item 1', id: 200244 }
// , { name: 'Item 2', id: 200134 }
// , { name: 'Item 3', id: 200179 }
// , { name: 'Item 3 SubItem 1', id: 200146 }
// , { name: 'Item 4', id: 200133 }
// , { name: 'Item 5', id: 200135 }
// , { name: 'Item 5 SubItem 1', id: 200146 }
// ]
Here's a full program demonstration using the flatMap
implementation provided here. Feel free to use it or any other implementation of your choosing :)
const flatMap = (f, xs = []) =>
xs.reduce ((acc, x) => acc.concat (f (x)), [])
const data =
[ { name: "Item 1"
, id: 200244
, siblings: []
}
, { name: "Item 2"
, id: 200134
, siblings: []
}
, { name: "Item 3"
, id: 200179
, siblings:
[ { name: "Item 3 SubItem 1"
, id: 200146
}
]
}
, { name: "Item 4"
, id: 200133
, siblings: []
}
, { name: "Item 5"
, id: 200135
, siblings:
[ { name: "Item 5 SubItem 1"
, id: 200146
}
]
}
]
const result =
flatMap (({ siblings = [], ...item }) => [ item, ...siblings ], data)
console.log (result)
// [ { name: 'Item 1', id: 200244 }
// , { name: 'Item 2', id: 200134 }
// , { name: 'Item 3', id: 200179 }
// , { name: 'Item 3 SubItem 1', id: 200146 }
// , { name: 'Item 4', id: 200133 }
// , { name: 'Item 5', id: 200135 }
// , { name: 'Item 5 SubItem 1', id: 200146 }
// ]