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

如何在Google Apps Script中按特定条件分配数组

Google Apps Script 数组分组分配实现方案

需求概述

现有三类数组需按规则完成分配:

  • 人员数组:var array1 = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18]
  • 日期数组:var array2 = ["date1","date2","date3","date4"]
  • 日期分组数组:每个日期对应一组分组,例如date1Groups = [[1,6,7,8],[4,5,9],[6,17,15,3,11]],其余日期对应date2Groups、date3Groups、date4Groups

分配规则:

  1. 按日期数量比例分配人员:示例中18人分4组,需生成2个含5元素、2个含4元素的数组
  2. 单个日期的结果数组中,任意两个元素不能同时出现在该日期的任一分组内(如6和8同属date1的一个分组,则不能同时出现在date1的结果数组中)

实现步骤与代码

完整代码实现

function allocatePersonnel() {
  // 原始数据
  const array1 = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18];
  const dateList = ["date1","date2","date3","date4"];
  // 日期分组映射,统一管理各日期的分组数据
  const dateGroupsMap = {
    date1: [[1,6,7,8],[4,5,9],[6,17,15,3,11]],
    date2: [[2,10,12],[3,13,16],[7,14,18]], // 示例分组,可替换为实际数据
    date3: [[5,11,15],[8,17,1],[4,12,16]], // 示例分组,可替换为实际数据
    date4: [[9,10,13],[2,6,14],[3,7,18]]  // 示例分组,可替换为实际数据
  };

  // 为每个日期构建冲突映射表:快速查询某人员的所有冲突对象
  const conflictMap = {};
  dateList.forEach(date => {
    conflictMap[date] = new Map();
    const groups = dateGroupsMap[date];
    groups.forEach(group => {
      group.forEach(person => {
        const conflicts = new Set(group.filter(p => p !== person));
        conflictMap[date].set(person, conflicts);
      });
    });
  });

  // 计算每个日期应分配的人数
  const totalPersons = array1.length;
  const dateCount = dateList.length;
  const baseCount = Math.floor(totalPersons / dateCount);
  const extraCount = totalPersons % dateCount;
  const targetCounts = dateList.map((_, index) => index < extraCount ? baseCount + 1 : baseCount);

  // 初始化结果数组,先分配前dateCount个人员到各数组
  const resultArrays = dateList.map((_, index) => [array1[index]]);
  const remainingPersons = array1.slice(dateCount);

  // 遍历剩余人员,逐个分配到符合条件的数组
  remainingPersons.forEach(person => {
    for (let i = 0; i < resultArrays.length; i++) {
      const currentArray = resultArrays[i];
      const date = dateList[i];
      let canAdd = true;

      // 检查当前人员与数组中已有元素是否冲突
      for (const p of currentArray) {
        if (conflictMap[date].has(p) && conflictMap[date].get(p).has(person)) {
          canAdd = false;
          break;
        }
      }

      // 符合条件则加入数组
      if (canAdd && currentArray.length < targetCounts[i]) {
        currentArray.push(person);
        break;
      }
    }
  });

  // 输出结果,可按需调整格式
  console.log("分配结果:");
  dateList.forEach((date, index) => {
    console.log(`${date}:`, resultArrays[index]);
  });
  return resultArrays;
}

关键逻辑说明

  • 冲突映射表:将每个日期的分组转换为Map结构,键为人员ID,值为该人员的所有冲突人员集合,避免重复遍历原始分组,提升检查效率
  • 人数分配逻辑:通过取整和取余计算每个日期的目标人数,保证分配比例符合总人数与日期数量的对应关系
  • 人员分配逻辑:遍历剩余人员,对每个人员依次检查各日期的结果数组,找到第一个无冲突且未达人数上限的数组加入,确保分配过程完全符合规则

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 03:55:30