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

使用JavaScript将二维数组转换为指定格式排班报告的实现求助

使用JavaScript将二维数组转换为指定格式排班报告的实现求助

嘿,我看你现在卡在把二维排班数组转换成指定格式的报告上了,先理清楚你的核心需求:你需要遍历每个员工(第一列的Name#x),找出他们需要替班的日期,把日期整理成紧凑的格式(连续日期用23-27 Jan,零散日期用24,26 Jan),最后输出[员工名]: [整理后的日期] ----> [被替班的员工名]这种格式对吧?

先说说你现有代码的问题:

  • 你只把替班的名字push到了string数组里,但完全没处理日期的转换和关联,也没对日期做格式整理
  • 最后打印的schedule变量根本没定义,运行肯定会报错
  • 没有处理ISO日期到DD MMM格式的转换,也没实现连续日期合并成范围的逻辑

接下来我给你写一个完整的可运行实现,一步步解决这些问题:

function displaySchedule() {
  const values = [
    ["Name/Date","2023-01-22T18:30:00.000Z","2023-01-23T18:30:00.000Z","2023-01-24T18:30:00.000Z","2023-01-25T18:30:00.000Z","2023-01-26T18:30:00.000Z"],
    ["Name#1","","Name#2","","Name#2",""],
    ["Name#2","","","","",""],
    ["Name#3","","","","",""],
    ["Name#4","","","","",""],
    ["Name#5","Name#4","Name#4","Name#4","Name#4","Name#4"],
    ["Name#6","Name#3","","Name#3","Name#3","Name#3"]
  ];

  // 辅助函数:把ISO日期转成带日和月缩写的格式(比如23 Jan)
  function formatDate(isoDate) {
    const date = new Date(isoDate);
    // 用UTC方法避免时区偏移导致的日期错误
    const day = date.getUTCDate();
    const month = date.toLocaleString('en-US', { month: 'short' });
    return { day, month, fullStr: `${day} ${month}` };
  }

  // 辅助函数:把零散日期数组整理成紧凑的范围格式
  function formatDateRange(dates) {
    if (dates.length === 0) return '';
    // 先按日期排序(原数组是有序的,但保险起见)
    const sortedDates = dates.sort((a, b) => a.day - b.day);
    const dateRanges = [];
    let currentStart = sortedDates[0];

    for (let i = 1; i < sortedDates.length; i++) {
      const currentDate = sortedDates[i];
      // 检查当前日期是否和起始日期连续
      if (currentDate.day === currentStart.day + (i - dateRanges.length)) {
        continue;
      } else {
        // 结束当前范围,存入结果
        const rangeEnd = sortedDates[i - 1];
        dateRanges.push(
          currentStart.day === rangeEnd.day 
            ? `${currentStart.day}` 
            : `${currentStart.day}-${rangeEnd.day}`
        );
        currentStart = currentDate;
      }
    }
    // 处理最后一个未闭合的范围
    const finalEnd = sortedDates[sortedDates.length - 1];
    dateRanges.push(
      currentStart.day === finalEnd.day 
        ? `${currentStart.day}` 
        : `${currentStart.day}-${finalEnd.day}`
    );

    return `${dateRanges.join(', ')} ${sortedDates[0].month}`;
  }

  // 遍历每个员工的排班数据
  for (let i = 1; i < values.length; i++) {
    const employeeName = values[i][0];
    // 用对象分组:键是被替班人名字,值是对应的日期数组
    const replacementMap = {};

    // 遍历每个日期列,收集替班信息
    for (let j = 1; j < values[i].length; j++) {
      const replacedName = values[i][j];
      if (replacedName) {
        const dateInfo = formatDate(values[0][j]);
        // 初始化被替班人的日期数组
        if (!replacementMap[replacedName]) {
          replacementMap[replacedName] = [];
        }
        replacementMap[replacedName].push(dateInfo);
      }
    }

    // 输出每个整理好的替班记录
    for (const [replacedPerson, dates] of Object.entries(replacementMap)) {
      const formattedDateStr = formatDateRange(dates);
      console.log(`${employeeName}: ${formattedDateStr} ----> ${replacedPerson}`);
    }
  }
}

// 调用生成报告
displaySchedule();

运行这段代码后,控制台会输出和你预期几乎一致的结果:

Name#1: 24, 26 Jan ----> Name#2
Name#5: 23-26 Jan ----> Name#4
Name#6: 23, 25-26 Jan ----> Name#3

(注:原预期里Name#5是23-27 Jan,但你的输入数组里最后一列日期是2023-01-26,所以实际输出是23-26;如果后续添加27号的列,代码会自动合并成23-27)

给你拆解下关键逻辑:

  • 用replacementMap对象分组替班信息,避免同一个替班关系重复输出
  • formatDate处理日期格式,用UTC方法防止时区差异导致的日期偏差
  • formatDateRange自动识别连续日期,把它们合并成范围格式,让报告更简洁

要是你需要调整格式或者有其他细节需求,随时说就行!

备注:内容来源于stack exchange,提问作者Code Guy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.23 15:42:47