I’ve got an array of objects that each carry a columnSpan
property with a numeric value between 1 and 16.
[
{
"columnSpan": 4,
"id": "DatoCmsEntry-MaixsOYtSwS7mloD59Rvng"
},
{
"columnSpan": 4,
"id": "DatoCmsEntry-fEuNly9-QFiRh4DoUZ-Y_w"
},
{
"columnSpan": 2,
"id": "DatoCmsEntry-HsAgXDMHQkSXS_4lKSGfGA"
},
{
"columnSpan": 2,
"id": "DatoCmsEntry-BM-fSBruSM67IFzCrBSLBg"
},
{
"columnSpan": 3,
"id": "DatoCmsEntry-JPushhKGSBCwR_uWcwIFSw"
},
{
"columnSpan": 3,
"id": "DatoCmsEntry-Q0sfjP9ZQZSDZZVP_sI9ew"
},
{
"columnSpan": 2,
"id": "DatoCmsEntry-CdVhbQENQ4ib2z4w3wc20Q"
},
{
"columnSpan": 2,
"id": "DatoCmsEntry-Fn2U_0CuQDiBEOZLmS3ovQ"
}
]
I need to split this array up into a multidimensional array where each top-level item represents a collection of records where the total columnSpan
is 16 or less, keeping the original order, like this:
[
[
{
"columnSpan": 4,
"id": "DatoCmsEntry-MaixsOYtSwS7mloD59Rvng"
},
{
"columnSpan": 4,
"id": "DatoCmsEntry-fEuNly9-QFiRh4DoUZ-Y_w"
},
{
"columnSpan": 2,
"id": "DatoCmsEntry-HsAgXDMHQkSXS_4lKSGfGA"
},
{
"columnSpan": 2,
"id": "DatoCmsEntry-BM-fSBruSM67IFzCrBSLBg"
},
{
"columnSpan": 3,
"id": "DatoCmsEntry-JPushhKGSBCwR_uWcwIFSw"
}
],
[
{
"columnSpan": 3,
"id": "DatoCmsEntry-Q0sfjP9ZQZSDZZVP_sI9ew"
},
{
"columnSpan": 2,
"id": "DatoCmsEntry-CdVhbQENQ4ib2z4w3wc20Q"
},
{
"columnSpan": 2,
"id": "DatoCmsEntry-Fn2U_0CuQDiBEOZLmS3ovQ"
}
]
]
Suggestions on ways to pull this off?
Reduce the array. In the reducer start by checking if a new chunk should be added. Always add the current item to the last chunk.
const fn = (arr, max) => arr.reduce((acc, o) => {
// add a new chunk and reset sum if no chunks, or next item would go over the max
if(!acc.res.length || acc.sum + o.columnSpan > max) {
acc.sum = 0
acc.res.push([])
}
acc.res.at(-1).push(o) // push current item to last chunk
acc.sum += o.columnSpan // add current columnSpan to sum
return acc
}, { res: [], sum: 0 }).res
const data = [{"columnSpan":4,"id":"DatoCmsEntry-MaixsOYtSwS7mloD59Rvng"},{"columnSpan":4,"id":"DatoCmsEntry-fEuNly9-QFiRh4DoUZ-Y_w"},{"columnSpan":2,"id":"DatoCmsEntry-HsAgXDMHQkSXS_4lKSGfGA"},{"columnSpan":2,"id":"DatoCmsEntry-BM-fSBruSM67IFzCrBSLBg"},{"columnSpan":3,"id":"DatoCmsEntry-JPushhKGSBCwR_uWcwIFSw"},{"columnSpan":3,"id":"DatoCmsEntry-Q0sfjP9ZQZSDZZVP_sI9ew"},{"columnSpan":2,"id":"DatoCmsEntry-CdVhbQENQ4ib2z4w3wc20Q"},{"columnSpan":2,"id":"DatoCmsEntry-Fn2U_0CuQDiBEOZLmS3ovQ"}]
const result = fn(data, 16)
console.log(result)