【问题标题】:How to reduce an array of timestamps to an array of counts of the number of elements within a particular time range如何将时间戳数组减少为特定时间范围内元素数量的计数数组
【发布时间】:2017-05-08 16:26:27
【问题描述】:

我有一个看起来像的数组

[
  "2017-05-08T13:42:00.318Z",
  "2017-05-08T13:42:05.590Z",
  "2017-05-08T13:42:12.377Z",
  "2017-05-08T13:42:20.830Z",
  "2017-05-08T13:42:22.634Z",
  "2017-05-08T13:42:25.249Z"
]

我想得到一个包含多少个时间戳落在 10 秒时间范围内的数组。

因此对于上述示例,"2017-05-08T13:42:00.318Z""2017-05-08T13:42:05.590Z" 将落入2017-05-08T13:42:00.000Z2017-05-08T13:42:10.000Z 的范围内。

"2017-05-08T13:42:12.377Z" 将落入2017-05-08T13:42:10.000Z2017-05-08T13:42:20.000Z 的范围内。

"2017-05-08T13:42:20.830Z""2017-05-08T13:42:22.634Z""2017-05-08T13:42:25.249Z" 将落入2017-05-08T13:42:20.000Z2017-05-08T13:42:30.000Z 的范围内。

我的目标是获取每个范围内时间戳数的数组。对于上面的示例,结果将是:[2, 1, 3]

注意:我正在使用 Typescript,因此使用 ES6 功能的答案将起作用。

【问题讨论】:

  • 到目前为止您尝试过什么?提示:使用 es6 filter 可能是一种方法。但如果没问题,它会返回一个新数组。

标签: javascript arrays time


【解决方案1】:

您可以将日期切片并与上一个日期进行检查。

          value                  slot           result
------------------------  ------------------  ---------
2017-05-08T13:42:00.318Z  2017-05-08T13:42:0  [1]
2017-05-08T13:42:05.590Z  2017-05-08T13:42:0  [2]
2017-05-08T13:42:12.377Z  2017-05-08T13:42:1  [2, 1]
2017-05-08T13:42:20.830Z  2017-05-08T13:42:2  [2, 1, 1]
2017-05-08T13:42:22.634Z  2017-05-08T13:42:2  [2, 1, 2]
2017-05-08T13:42:25.249Z  2017-05-08T13:42:2  [2, 1, 3]

var data = ["2017-05-08T13:42:00.318Z", "2017-05-08T13:42:05.590Z", "2017-05-08T13:42:12.377Z", "2017-05-08T13:42:20.830Z", "2017-05-08T13:42:22.634Z", "2017-05-08T13:42:25.249Z"],
    count = data.reduce(function (r, a, i, aa) {
        if (i && aa[i - 1].slice(0, 18) === a.slice(0, 18)) {
            r[r.length - 1]++;
        } else {
            r.push(1);
        }
        return r;
    }, []);

console.log(count)

【讨论】:

  • 这段代码看起来不错,但它严格固定为 10 秒
  • @Redu,10 秒是问题的一部分。
【解决方案2】:

这可以使用一些我并不特别引以为豪的循环来工作,但是您可以更改间隔,如果您只使用 forEach 自己调用的函数,它可以在以后考虑更多数据。

const timestampsToCheck = [
  "2017-05-08T13:42:00.318Z",
  "2017-05-08T13:42:05.590Z",
  "2017-05-08T13:42:12.377Z",
  "2017-05-08T13:42:20.830Z",
  "2017-05-08T13:42:22.634Z",
  "2017-05-08T13:42:25.249Z"
];

let nextTime = null;
let outputTime = [0];

function getNextTime() {
  nextTime.setSeconds(nextTime.getSeconds() + 10);
}

timestampsToCheck.forEach((element) => {

  let thisTime = new Date(element);
  let outputLast = outputTime.length - 1;

  if (nextTime === null) {
    nextTime = thisTime;
    getNextTime();
    outputTime[outputLast]++;
  } else if (thisTime > nextTime) {
    getNextTime();
    while (thisTime > nextTime) {
      getNextTime();
      outputTime.push(0);
    }
    outputTime.push(1);
  } else {
    outputTime[outputLast]++;
  }
});

console.log(outputTime);

【讨论】:

    【解决方案3】:
    const timestampsToCheck = [
      '2017-05-08T13:42:00.318Z',
      '2017-05-08T13:42:05.590Z',
      '2017-05-08T13:42:12.377Z',
      '2017-05-08T13:42:20.830Z',
      '2017-05-08T13:42:22.634Z',
      '2017-05-08T13:42:25.249Z',
    ];
    
    const ranges = [
      ['2017-05-08T13:42:00.000Z', '2017-05-08T13:42:10.000Z'],
      ['2017-05-08T13:42:10.000Z', '2017-05-08T13:42:20.000Z'],
      ['2017-05-08T13:42:20.000Z', '2017-05-08T13:42:30.000Z'],
    ];
    
    const timestampsInRange = ranges.reduce((acc, range) => {
      const count = timestampsToCheck.reduce((innerAcc, time) => {
        return innerAcc + ((time > range[0] && time < range[1]) ? 1 : 0);
      }, 0);
      return acc.concat(count);
    }, []);
    
    console.log(timestampsInRange);
    

    工作小提琴:https://jsfiddle.net/9tjerwxa/

    【讨论】:

      猜你喜欢
      • 2014-03-25
      • 2012-12-11
      • 2018-12-28
      • 2023-03-03
      • 1970-01-01
      • 1970-01-01
      • 2022-11-22
      • 1970-01-01
      • 2013-02-20
      相关资源
      最近更新 更多