如何在Apps Script中实现符合长度限制的数组最优拆分?
Apps Script 数组均匀拆分函数(满足长度范围要求)
需求说明
需要实现一个函数,将大数组拆分为若干子数组,要求:
- 子数组最优长度为15,实际长度必须在10-20之间
- 拆分尽可能均匀,保持原数组元素顺序
- 示例规则:
- 长度21 → [10, 11]
- 长度22 → [11, 11]
- 长度36 → [18, 18]
- 长度37 → [12, 12, 13]
- 长度38 → [12, 13, 13]
原代码问题分析
原代码的核心问题在于子数组数量的计算逻辑未限制在合法范围内,且余数分配方向不符合示例要求:
- 使用
Math.round(total/optimalSize)计算子数组数量时,未确保拆分后的子数组长度落在10-20区间内 - 余数优先分配给前几个子数组,与示例中余数分配给后几个的规则不符
修正后的代码
function splitList(values) { const total = values.length; const optimalSize = 15; const minSize = 10; const maxSize = 20; // 特殊情况:数组长度小于等于最小子数组长度,直接返回原数组 if (total <= minSize) { return [values]; } // 计算合法的子数组数量范围 const minNum = Math.ceil(total / maxSize); // 最少需要的子数组数量(每个子数组最大20) const maxNum = Math.floor(total / minSize); // 最多能拆的子数组数量(每个子数组最小10) // 在合法范围内,找到最接近最优数量(total/optimalSize)的子数组数量 let numSublists = minNum; let closestDiff = Math.abs(total / optimalSize - minNum); for (let i = minNum + 1; i <= maxNum; i++) { const diff = Math.abs(total / optimalSize - i); if (diff < closestDiff) { closestDiff = diff; numSublists = i; } } // 计算基础子数组长度和余数 const baseSize = Math.floor(total / numSublists); const remainder = total % numSublists; const result = []; let startIndex = 0; // 拆分逻辑:前(numSublists - remainder)个为基础长度,后remainder个为基础长度+1(符合示例余数分配规则) for (let i = 0; i < numSublists; i++) { const currentSize = baseSize + (i >= numSublists - remainder ? 1 : 0); result.push(values.slice(startIndex, startIndex + currentSize)); startIndex += currentSize; } return result; } // 示例验证 console.log("长度21的拆分结果:", splitList(Array.from({length:21},(_,i)=>i+1))); // [[1-10], [11-21]] console.log("长度22的拆分结果:", splitList(Array.from({length:22},(_,i)=>i+1))); // [[1-11], [12-22]] console.log("长度36的拆分结果:", splitList(Array.from({length:36},(_,i)=>i+1))); // [[1-18], [19-36]] console.log("长度37的拆分结果:", splitList(Array.from({length:37},(_,i)=>i+1))); // [[1-12], [13-24], [25-37]] console.log("长度38的拆分结果:", splitList(Array.from({length:38},(_,i)=>i+1))); // [[1-12], [13-25], [26-38]]
代码解释
- 合法数量范围计算:通过
minNum和maxNum确保拆分后的子数组长度必然落在10-20之间 - 最优数量选择:在合法范围内挑选最接近
total/15的子数组数量,保证拆分结果尽可能接近最优长度 - 余数分配逻辑:将余数分配给最后几个子数组,与示例规则一致,实现均匀拆分
- 边界处理:单独处理长度小于等于10的数组,直接返回原数组
内容的提问来源于stack exchange,提问作者arlovande
相关产品推荐
相关产品推荐

