如何按columnSpan总和≤16将对象数组拆分为多维数组?
按columnSpan总和分组的实现方法
给定一个包含columnSpan属性(值为1-16)的对象数组,需要将其拆分为多维数组,每组内所有对象的columnSpan总和不超过16,同时保留原数组顺序,这里分享几种实用的实现思路:
1. 普通循环遍历法
这是最直观的实现方式,通过维护当前分组和结果数组,逐个判断元素是否能加入当前分组:
const input = [ { "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 groupByColumnSpan = (arr, maxSum = 16) => { const result = []; let currentGroup = []; let currentSum = 0; for (const item of arr) { if (currentSum + item.columnSpan <= maxSum) { currentGroup.push(item); currentSum += item.columnSpan; } else { result.push(currentGroup); currentGroup = [item]; currentSum = item.columnSpan; } } // 把最后一组加入结果 if (currentGroup.length > 0) { result.push(currentGroup); } return result; }; console.log(groupByColumnSpan(input));
2. Array.reduce() 简化实现
利用数组的reduce方法,用累加器同时维护当前分组和结果数组,代码更简洁:
const groupByColumnSpan = (arr, maxSum = 16) => { const [result, currentGroup] = arr.reduce((acc, item) => { const [res, currGroup, currSum] = acc; if (currSum + item.columnSpan <= maxSum) { currGroup.push(item); return [res, currGroup, currSum + item.columnSpan]; } else { res.push(currGroup); return [res, [item], item.columnSpan]; } }, [[], [], 0]); // 补充最后一组 if (currentGroup.length) result.push(currentGroup); return result; }; // 调用方式同上 console.log(groupByColumnSpan(input));
3. 生成器函数(懒加载分组)
如果处理的数组数据量很大,用生成器函数可以按需生成分组,避免一次性占用过多内存:
function* groupByColumnSpan(arr, maxSum = 16) { let currentGroup = []; let currentSum = 0; for (const item of arr) { if (currentSum + item.columnSpan <= maxSum) { currentGroup.push(item); currentSum += item.columnSpan; } else { yield currentGroup; currentGroup = [item]; currentSum = item.columnSpan; } } if (currentGroup.length > 0) { yield currentGroup; } } // 使用方式: const groups = Array.from(groupByColumnSpan(input)); console.log(groups);
以上三种方法都能满足需求:普通循环适合新手理解,reduce写法更简洁,生成器则适合大数据量场景。
内容的提问来源于stack exchange,提问作者Brandon Durham
相关产品推荐
相关产品推荐

