You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Apps Script中实现符合长度限制的数组最优拆分?

Apps Script 数组均匀拆分函数(满足长度范围要求)

需求说明

需要实现一个函数,将大数组拆分为若干子数组,要求:

  • 子数组最优长度为15,实际长度必须在10-20之间
  • 拆分尽可能均匀,保持原数组元素顺序
  • 示例规则:
    • 长度21 → [10, 11]
    • 长度22 → [11, 11]
    • 长度36 → [18, 18]
    • 长度37 → [12, 12, 13]
    • 长度38 → [12, 13, 13]

原代码问题分析

原代码的核心问题在于子数组数量的计算逻辑未限制在合法范围内,且余数分配方向不符合示例要求:

  1. 使用Math.round(total/optimalSize)计算子数组数量时,未确保拆分后的子数组长度落在10-20区间内
  2. 余数优先分配给前几个子数组,与示例中余数分配给后几个的规则不符

修正后的代码

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]]

代码解释

  1. 合法数量范围计算:通过minNum和maxNum确保拆分后的子数组长度必然落在10-20之间
  2. 最优数量选择:在合法范围内挑选最接近total/15的子数组数量,保证拆分结果尽可能接近最优长度
  3. 余数分配逻辑:将余数分配给最后几个子数组,与示例规则一致,实现均匀拆分
  4. 边界处理:单独处理长度小于等于10的数组,直接返回原数组

内容的提问来源于stack exchange,提问作者arlovande

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 00:14:52