js 根据已有的日期数组,生成365天的数组,将已有的日期填写在数组对应的位置?

js 根据已有的日期数组,生成365天的数组,将已有的日期填写在数组对应的位置,没有的日期填写空,
请问这个函数怎么写?

假如:

let arr = ["2019/1/1", "2019/1/4", "2019/1/6"]

要生成结果数组

result = ["2019/1/1",,,"2019/1/4",,"2019/1/6",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,]; // 365个数据
阅读 1.6k
avatarAI BotBETA

在JavaScript中,直接创建具有空位的数组(如[, ,,]中的逗号)是不被允许的,因为这将导致语法错误。不过,你可以使用undefinednull作为占位符,并在后续处理中将其视为空值。

以下是一个可能的函数实现,该函数接受一个日期数组,并生成一个包含365天(假设是闰年以外的年份)的数组,其中已知的日期将填写在正确的位置,其余位置为undefined

function generateYearArray(dates) {
    // 创建一个映射,将日期字符串映射到它们的索引(从0开始的日期偏移)
    const dateMap = dates.reduce((map, dateString, index) => {
        const date = new Date(dateString);
        const dayOfYear = getDayOfYear(date); // 自定义函数,获取一年中的第几天
        map[dayOfYear] = dateString;
        return map;
    }, {});

    // 自定义函数,获取一年中的第几天
    function getDayOfYear(date) {
        const start = new Date(date.getUTCFullYear(), 0, 0);
        const diff = date - start + ((start.getTimezoneOffset() - date.getTimezoneOffset()) * 60 * 1000);
        const oneDay = 1000 * 60 * 60 * 24;
        return Math.floor(diff / oneDay);
    }

    // 创建一个长度为365的数组,并使用映射填充已知的日期
    const result = Array.from({ length: 365 }, (_, i) => dateMap[i] || undefined);
    return result;
}

// 示例使用
let arr = ["2019-01-01", "2019-01-04", "2019-01-06"];
let result = generateYearArray(arr);
console.log(result);
// 输出类似:[ '2019-01-01', undefined, undefined, '2019-01-04', undefined, '2019-01-06', ... ]

注意:这个实现假设输入的日期字符串都是有效且按照升序排列的。如果日期字符串可能无效或未排序,你需要在将日期添加到映射之前添加额外的验证和排序步骤。

此外,由于JavaScript数组中的空位(undefined)在大多数操作中都被视为有效的元素,因此你可以将上述undefined视为空位。如果你需要在后续处理中明确区分undefined和有效的日期值,你可以使用其他占位符(如null或特殊字符串)来代替。

4 个回答
  const arr = ["2019/1/1", "2019/1/4", "2019/1/6"]

  // js 根据已有的日期数组,生成365天的数组,将已有的日期填写在数组对应的位置,没有的日期填写空
  function getDateArray(activeDates) {
    const dateArray = []
    for (let i = 0; i < 365; i++) {
      const date = new Date(2019, 0, 1)
      date.setDate(date.getDate() + i)
      const dateStr = date.toLocaleDateString()
      if (activeDates.includes(dateStr)) {
        dateArray.push(dateStr)
      } else {
        dateArray.push('')
      }
    }
    return dateArray
  }

  console.log(getDateArray(arr));
let result = arr.reduce((a, i) => {
    a[(new Date(i) - new Date('2019-01-01')) / 864e5] = i
    return a
}, Array.from({length: 366}))

用Raccoon把你的问题描述了一下,生成以下代码:

function generateDatesArray(year, needArray) {
  const dates = [];
  const specialDates = needArray;

  for (let date = new Date(year, 0, 1); date <= new Date(year, 11, 31); date.setDate(date.getDate() + 1)) {
    const formattedDate = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;
    if (specialDates.includes(formattedDate)) {
      dates.push(formattedDate);
    } else {
      dates.push(null);
    }
  }

  return dates;
}

const needArray = ['2023-01-01', '2023-02-02', '2023-03-03', '2023-04-04', '2023-05-05', '2023-06-06', '2023-07-07'];
const datesArray = generateDatesArray(2023, needArray);

输出结果如下图:
image.png

和你的要求不一样的地方在于,不存在的日期我用了null填充

这样写,年份和已存在日期你都可以自己传参

const arr = ['2024-5-1', '2024/6/14', '2024-03-01', '2025/3/1']

/**
 * @description: 时间填充,传入含有多个日期的数组,依照顺序填充数组
 * @param {Array} arr 时间数组
 * @param {Object} option 配置项
 * @param {Boolean} option.yearStart 是以最小日期的年份1月1日开始还是以最小日期为开始,默认true
 * @param {Boolean} option.format 是否格式化时间,默认true,使用toLocaleDateString,可添加格式化工具,统一格式
 * @param {String} option.placeholder 空值占位符,默认''
 * @param {Number} option.length 数组长度,默认 365
 * @return {Array} 时间填充后的数组
 */
const timeFill = (arr, option) => {
  const { yearStart = true, format = true, placeholder = '', length = 365 } = option || {}
  if (arr.length === 0) {
    return []
  }
  const dateList = arr.sort((a, b) => new Date(a) - new Date(b))
  const startDate = new Date(dateList[0])
  const startYear = startDate.getFullYear()
  const startTime = yearStart ? new Date(startYear, 0, 1).getTime() : startDate.getTime()
  const timeArr = Array.from({ length }, () => placeholder)
  dateList.forEach(item => {
    const index = Math.floor((new Date(item).getTime() - startTime) / 1000 / 60 / 60 / 24)
    if (index < timeArr.length) {
      timeArr[index] = format ? new Date(item).toLocaleDateString() : item
    }
  })
  return timeArr
}

console.log(timeFill(arr))
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏