如何按时间步长分组数组项

3

我有一个像这样的数组:

let arr = [
  {
    title: 'Some title',
    start: '09:30:59',
    end: '09:33:59',
  },
  {
    title: 'Some title',
    start: '09:33:59',
    end: '09:35:59',
  },
  {
    title: 'Some title',
    start: '09:35:59',
    end: '09:40:59',
  },
  {
    title: 'Some title',
    start: '09:30:59',
    end: '09:45:59',
  }
  ...
];

我希望能够按照一定的步长(例如10)对数组进行分组:

let result = [
  {
    start: '09:30:59',
    end: '09:40:59',
    arr: [
      {
        title: 'Some title',
        start: '09:30:59',
        end: '09:33:59',
      },
      {
        title: 'Some title',
        start: '09:33:59',
        end: '09:35:59',
      },
    ],
  }, 
  {
    start: '09:40:59',
    end: '09:50:59',
    arr: [
      {
        title: 'Some title',
        start: '09:35:59',
        end: '09:40:59',
      },
      {
        title: 'Some title',
        start: '09:30:59',
        end: '09:45:59',
      }
    ],
  },        
    ...
];

我试图去做它:

let step = 10;
let diffMinutes = dayjs(arr[arr.length - 1].end).diff(arr[0].start, 'm') / step;
let newArr  = [];
let result = [];
for (let t = 0; t < diffMinutes; t++) {
  newArr = [];
  for (let i = 0; i < arr.length; i++) {
    if (dayjs(arr[i].start).isBetween(arr[0].start, dayjs(arr[0].start).add(step, 'm').format('YYYY-MM-DD HH:mm'))) {
      newArr.push(state.events[i]);
    }
  }
  result.push(
    {
      ...
      arr: newArr
    }
  )
}       

我使用了dayjs添加了一个条件,检查事件开始时间是否进入了某个时间段。我认为这可以比我做的更容易。 结果应该是按10分钟为单位分组的数组。 假设在else语句中,我应该使用上一个数组结果的最后一项。 但是它仅适用于第一次迭代,我不知道如何在下一次迭代中实现。

请帮帮我。


这似乎是一个类似于合并区间(https://leetcode.com/problems/merge-intervals/)的问题。你可以去看看,那里有一个解决方案选项卡。 - vitkarpov
2个回答

3
你可以取时间的前四个字符,然后按此值进行分组。

let array = [{ title: 'Some title', start: '09:30:59', end: '09:33:59' }, { title: 'Some title', start: '09:33:59', end: '09:35:59' }, { title: 'Some title', start: '09:35:59', end: '09:40:59' }, { title: 'Some title', start: '09:30:59', end: '09:45:59' }],
    group = s => s.slice(0, 4),
    result = Object.values(array.reduce((r, o) => {
        const key = group(o.start);
        r[key] = r[key] || { start: key + '0:00', array: [] };
        r[key].array.push(o);
        return r;
    }, {}));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

另一种解决方案可能是使用以秒为单位的时间值,并使用每几秒钟作为一个间隔。结果按照时间间隔分组,startend属性也会根据给定的间隔进行计算。

let array = [{ title: 'Some title', start: '09:30:59', end: '09:33:59' }, { title: 'Some title', start: '09:33:59', end: '09:35:59' }, { title: 'Some title', start: '09:35:59', end: '09:40:59' }, { title: 'Some title', start: '09:30:59', end: '09:45:59' }],
    seconds = time => time.split(':').reduce((a, b) => a * 60 + +b),
    //interval = 600,               // in seconds, here 10 minutes
    interval = seconds('00:10:00'), // or by taking the seconds from a time string
    group = time => Math.floor(seconds(time) / interval),
    getTime = seconds => [3600, 60, 1]
        .map(factor => {
            var v = Math.floor(seconds / factor);
            seconds %= factor;
            return v.toString().padStart(2, 0);
        })
        .join(':'),
    result = Object.values(array.reduce((r, o) => {
        const key = group(o.start);
        r[key] = r[key] || { start: getTime(key * interval), end: getTime((key + 1) * interval - 1), array: [] };
        r[key].array.push(o);
        return r;
    }, {}));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }


我理解这一点,但如何按时间间隔将这些项分组到数组中? - Andriy Yushko
你需要使用 dayjs 吗?如果是的话,你可以检查两个时间是否比你想要的间隔时间更短。如果不需要或者不能取差值,你可以获取所有总秒数并检查差值是否在所需范围内。 - Nina Scholz
是的,我使用 Dayjs 来检查时间段内的入场项目。 - Andriy Yushko

0

已解决问题 示例

let step = 5;
let diffMinutes = Math.round(
  dayjs(arr[arr.length - 1].end).diff(arr[0].start, "m") / step
);
let result = [];
let newArr = [];

for (var i = 0; i <= diffMinutes; i++) {
  newArr = [];
  if (i === 0) {
    for (let j = 0; j < arr.length; j++) {
      if (
        moment(arr[j].start).isSame(arr[0].start) ||
        moment(arr[j].start).isSame(
          dayjs(arr[0].start).add(step, "m").format("YYYY-MM-DD HH:mm:ss")
        ) ||
        moment(arr[j].start).isBetween(
          arr[0].start,
          dayjs(arr[0].start).add(step, "m").format("YYYY-MM-DD HH:mm:ss")
        )
      ) {
        newArr.push(arr[j]);
      }
    }
  } else {
    let lastResult = result[result.length - 1];
    let lastEllArr = lastResult[lastResult.length - 1];

    console.log("i" + i, lastEllArr.start);
    for (let j = 0; j < arr.length; j++) {
      if (
        moment(arr[j].start).isSame(
          dayjs(lastEllArr.end).add(step, "m").format("YYYY-MM-DD HH:mm:ss")
        ) ||
        moment(arr[j].start).isBetween(
          lastEllArr.end,
          dayjs(lastEllArr.end).add(step, "m").format("YYYY-MM-DD HH:mm:ss")
        )
      ) {
        newArr.push(arr[j]);
      }
    }
  }
  if (newArr.length !== 0) {
    result.push(newArr);
  }
}

如果有人提出改进代码的建议,我会非常感激。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接