【问题标题】:Split array of objects into 2hrs span groups将对象数组拆分为 2 小时跨度组
【发布时间】:2019-12-06 08:04:24
【问题描述】:

我需要将对象数组拆分为以下形状

{
  eventStart: 1575621000000,
  data: 'Some data' // not relevant
}

以 2 小时为单位,从整点(整点)开始,例如:10.00 - 12.00、12.00 - 14.00 等

这是我想出的,但不认为它是性能解决方案附近的任何地方:

请注意 day 只是一个 moment().startOf('day') const

data => data.reduce((acc, { eventStart, ...rest }) => {
    if (moment(eventStart).isBetween(moment(day).add(8, 'hours'), moment(day).add(10, 'hours'))) {
      acc = Object.assign(
        {},
        acc,
        { '8-10': [...acc['8-10'], rest] }
      )
    }
    if (moment(eventStart).isBetween(moment(day).add(10, 'hours'), moment(day).add(12, 'hours'))) {
      acc = Object.assign(
        {},
        acc,
        { '10-12': [...acc['10-12'], rest] }
      )
    }
    if (moment(eventStart).isBetween(moment(day).add(12, 'hours'), moment(day).add(14, 'hours'))) {
      acc = Object.assign(
        {},
        acc,
        { '12-14': [...acc['12-14'], rest] }
      )
    }
    if (moment(eventStart).isBetween(moment(day).add(14, 'hours'), moment(day).add(16, 'hours'))) {
      acc = Object.assign(
        {},
        acc,
        { '14-16': [...acc['14-16'], rest] }
      )
    }
    if (moment(eventStart).isBetween(moment(day).add(16, 'hours'), moment(day).add(18, 'hours'))) {
      acc = Object.assign(
        {},
        acc,
        { '16-18': [...acc['16-18'], rest] }
      )
    }
    if (moment(eventStart).isBetween(moment(day).add(18, 'hours'), moment(day).add(20, 'hours'))) {
      acc = Object.assign(
        {},
        acc,
        { '18-20': [...acc['18-20'], rest] }
      )
    }
    if (moment(eventStart).isBetween(moment(day).add(20, 'hours'), moment(day).add(22, 'hours'))) {
      acc = Object.assign(
        {},
        acc,
        { '20-22': [...acc['20-22'], rest] }
      )
    }
    if (moment(eventStart).isBetween(moment(day).add(22, 'hours'), moment(day).add(24, 'hours'))) {
      acc = Object.assign(
        {},
        acc,
        { '22-24': [...acc['22-24'], rest] }
      )
    }

    return acc
  }, {
    '8-10': [],
    '10-12': [],
    '12-14': [],
    '14-16': [],
    '16-18': [],
    '18-20': [],
    '20-22': [],
    '22-24': []
  })

如果有人想出一个 Lodash 方法,我很喜欢。

示例数据:

[{"data":42986084,"eventStart":1575621000000},{"data":43729858,"eventStart":1575626400000},{"data":43738365,"eventStart":1575626400000},{"data":43738483,"eventStart":1575626400000},{"data":43688900,"eventStart":1575626400000},{"data":43701367,"eventStart":1575628200000},{"data":43701506,"eventStart":1575628200000},{"data":43675303,"eventStart":1575621000000},{"data":43690259,"eventStart":1575621000000},{"data":43695785,"eventStart":1575628200000},{"data":43695820,"eventStart":1575628200000},{"data":43695827,"eventStart":1575628200000},{"data":43699341,"eventStart":1575628200000},{"data":43699369,"eventStart":1575628200000},{"data":43699424,"eventStart":1575628200000},{"data":43699428,"eventStart":1575628200000},{"data":43700003,"eventStart":1575628200000},{"data":43701004,"eventStart":1575628200000},{"data":43698552,"eventStart":1575628200000},{"data":43741641,"eventStart":1575619200000},{"data":43741909,"eventStart":1575619200000},{"data":43739045,"eventStart":1575624600000},{"data":43742137,"eventStart":1575624600000},{"data":43742680,"eventStart":1575619200000},{"data":43744043,"eventStart":1575619200000},{"data":43784844,"eventStart":1575619200000},{"data":43785707,"eventStart":1575624600000},{"data":43764294,"eventStart":1575621900000},{"data":43787721,"eventStart":1575622800000},{"data":43787722,"eventStart":1575622800000},{"data":43787723,"eventStart":1575622800000},{"data":43787737,"eventStart":1575622800000},{"data":43767839,"eventStart":1575621600000},{"data":43726394,"eventStart":1575626400000},{"data":43810835,"eventStart":1575628200000},{"data":43725116,"eventStart":1575618600000},{"data":43793011,"eventStart":1575622800000},{"data":43793046,"eventStart":1575626400000},{"data":43793062,"eventStart":1575628200000},{"data":43737559,"eventStart":1575619200000},{"data":43737939,"eventStart":1575619200000},{"data":43737938,"eventStart":1575624600000},{"data":43792981,"eventStart":1575624600000},{"data":43735362,"eventStart":1575621600000},{"data":43784352,"eventStart":1575619200000},{"data":43784392,"eventStart":1575619200000},{"data":43731320,"eventStart":1575624600000},{"data":43732363,"eventStart":1575624600000},{"data":43785780,"eventStart":1575622800000},{"data":43785782,"eventStart":1575622800000},{"data":43785790,"eventStart":1575628200000},{"data":43785792,"eventStart":1575628200000},{"data":43780474,"eventStart":1575621000000},{"data":43780213,"eventStart":1575624000000},{"data":43811157,"eventStart":1575626400000},{"data":43811324,"eventStart":1575626400000},{"data":43811121,"eventStart":1575628200000},{"data":41965260,"eventStart":1575624600000},{"data":43793228,"eventStart":1575622800000},{"data":43735069,"eventStart":1575626400000},{"data":43550395,"eventStart":1575621000000},{"data":43550795,"eventStart":1575628200000},{"data":43674957,"eventStart":1575619200000},{"data":43675056,"eventStart":1575619500000},{"data":43699933,"eventStart":1575626400000},{"data":43700079,"eventStart":1575626400000},{"data":43735147,"eventStart":1575626400000},{"data":43735110,"eventStart":1575626400000},{"data":43732832,"eventStart":1575626400000},{"data":43732877,"eventStart":1575626400000},{"data":43733772,"eventStart":1575626400000},{"data":43761754,"eventStart":1575626400000},{"data":43694264,"eventStart":1575622800000},{"data":43748186,"eventStart":1575626400000},{"data":43720156,"eventStart":1575622800000},{"data":43720671,"eventStart":1575622800000},{"data":43589280,"eventStart":1575626400000},{"data":43593385,"eventStart":1575626400000},{"data":43757509,"eventStart":1575619200000},{"data":43757556,"eventStart":1575621000000},{"data":43535382,"eventStart":1575619200000},{"data":43371974,"eventStart":1575626400000},{"data":43752370,"eventStart":1575621000000},{"data":43752371,"eventStart":1575621000000},{"data":43784503,"eventStart":1575619080000},{"data":43784761,"eventStart":1575620400000},{"data":43784650,"eventStart":1575621720000},{"data":43784748,"eventStart":1575623040000},{"data":43784836,"eventStart":1575624360000},{"data":43785638,"eventStart":1575625680000},{"data":43727654,"eventStart":1575619800000},{"data":43727744,"eventStart":1575622200000},{"data":43727655,"eventStart":1575624600000},{"data":43727728,"eventStart":1575627000000}]

预期的输出实际上是任何可迭代的形式。一个例子可能是 reduce 函数中的 initialValue:

{
    '8-10': [], // nothing found for this criteria
    '10-12': [
               {
                 eventStart: 1575626400000,
                 data: 444
               },
               {
                 eventStart: 1575626400000,
                 data: 555
               }
             ],  // 2 objects fit the 10-12 range
    '12-14': [], // nothing found for this criteria
    '14-16': [], // nothing found for this criteria
    '16-18': [], // nothing found for this criteria
    '18-20': [], // nothing found for this criteria
    '20-22': [], // nothing found for this criteria
    '22-24': [] // nothing found for this criteria
  }

为问题添加代码 sn-p 以供其他人运行和处理

day = moment().startOf('day')
data = [{"data":42986084,"eventStart":1575621000000},{"data":43729858,"eventStart":1575626400000},{"data":43738365,"eventStart":1575626400000},{"data":43738483,"eventStart":1575626400000},{"data":43688900,"eventStart":1575626400000},{"data":43701367,"eventStart":1575628200000},{"data":43701506,"eventStart":1575628200000},{"data":43675303,"eventStart":1575621000000},{"data":43690259,"eventStart":1575621000000},{"data":43695785,"eventStart":1575628200000},{"data":43695820,"eventStart":1575628200000},{"data":43695827,"eventStart":1575628200000},{"data":43699341,"eventStart":1575628200000},{"data":43699369,"eventStart":1575628200000},{"data":43699424,"eventStart":1575628200000},{"data":43699428,"eventStart":1575628200000},{"data":43700003,"eventStart":1575628200000},{"data":43701004,"eventStart":1575628200000},{"data":43698552,"eventStart":1575628200000},{"data":43741641,"eventStart":1575619200000},{"data":43741909,"eventStart":1575619200000},{"data":43739045,"eventStart":1575624600000},{"data":43742137,"eventStart":1575624600000},{"data":43742680,"eventStart":1575619200000},{"data":43744043,"eventStart":1575619200000},{"data":43784844,"eventStart":1575619200000},{"data":43785707,"eventStart":1575624600000},{"data":43764294,"eventStart":1575621900000},{"data":43787721,"eventStart":1575622800000},{"data":43787722,"eventStart":1575622800000},{"data":43787723,"eventStart":1575622800000},{"data":43787737,"eventStart":1575622800000},{"data":43767839,"eventStart":1575621600000},{"data":43726394,"eventStart":1575626400000},{"data":43810835,"eventStart":1575628200000},{"data":43725116,"eventStart":1575618600000},{"data":43793011,"eventStart":1575622800000},{"data":43793046,"eventStart":1575626400000},{"data":43793062,"eventStart":1575628200000},{"data":43737559,"eventStart":1575619200000},{"data":43737939,"eventStart":1575619200000},{"data":43737938,"eventStart":1575624600000},{"data":43792981,"eventStart":1575624600000},{"data":43735362,"eventStart":1575621600000},{"data":43784352,"eventStart":1575619200000},{"data":43784392,"eventStart":1575619200000},{"data":43731320,"eventStart":1575624600000},{"data":43732363,"eventStart":1575624600000},{"data":43785780,"eventStart":1575622800000},{"data":43785782,"eventStart":1575622800000},{"data":43785790,"eventStart":1575628200000},{"data":43785792,"eventStart":1575628200000},{"data":43780474,"eventStart":1575621000000},{"data":43780213,"eventStart":1575624000000},{"data":43811157,"eventStart":1575626400000},{"data":43811324,"eventStart":1575626400000},{"data":43811121,"eventStart":1575628200000},{"data":41965260,"eventStart":1575624600000},{"data":43793228,"eventStart":1575622800000},{"data":43735069,"eventStart":1575626400000},{"data":43550395,"eventStart":1575621000000},{"data":43550795,"eventStart":1575628200000},{"data":43674957,"eventStart":1575619200000},{"data":43675056,"eventStart":1575619500000},{"data":43699933,"eventStart":1575626400000},{"data":43700079,"eventStart":1575626400000},{"data":43735147,"eventStart":1575626400000},{"data":43735110,"eventStart":1575626400000},{"data":43732832,"eventStart":1575626400000},{"data":43732877,"eventStart":1575626400000},{"data":43733772,"eventStart":1575626400000},{"data":43761754,"eventStart":1575626400000},{"data":43694264,"eventStart":1575622800000},{"data":43748186,"eventStart":1575626400000},{"data":43720156,"eventStart":1575622800000},{"data":43720671,"eventStart":1575622800000},{"data":43589280,"eventStart":1575626400000},{"data":43593385,"eventStart":1575626400000},{"data":43757509,"eventStart":1575619200000},{"data":43757556,"eventStart":1575621000000},{"data":43535382,"eventStart":1575619200000},{"data":43371974,"eventStart":1575626400000},{"data":43752370,"eventStart":1575621000000},{"data":43752371,"eventStart":1575621000000},{"data":43784503,"eventStart":1575619080000},{"data":43784761,"eventStart":1575620400000},{"data":43784650,"eventStart":1575621720000},{"data":43784748,"eventStart":1575623040000},{"data":43784836,"eventStart":1575624360000},{"data":43785638,"eventStart":1575625680000},{"data":43727654,"eventStart":1575619800000},{"data":43727744,"eventStart":1575622200000},{"data":43727655,"eventStart":1575624600000},{"data":43727728,"eventStart":1575627000000}]

res = data.reduce((acc, { eventStart, ...rest }) => {
    if (moment(eventStart).isBetween(moment(day).add(8, 'hours'), moment(day).add(10, 'hours'))) {
      acc = Object.assign(
        {},
        acc,
        { '8-10': [...acc['8-10'], rest] }
      )
    }
    if (moment(eventStart).isBetween(moment(day).add(10, 'hours'), moment(day).add(12, 'hours'))) {
      acc = Object.assign(
        {},
        acc,
        { '10-12': [...acc['10-12'], rest] }
      )
    }
    if (moment(eventStart).isBetween(moment(day).add(12, 'hours'), moment(day).add(14, 'hours'))) {
      acc = Object.assign(
        {},
        acc,
        { '12-14': [...acc['12-14'], rest] }
      )
    }
    if (moment(eventStart).isBetween(moment(day).add(14, 'hours'), moment(day).add(16, 'hours'))) {
      acc = Object.assign(
        {},
        acc,
        { '14-16': [...acc['14-16'], rest] }
      )
    }
    if (moment(eventStart).isBetween(moment(day).add(16, 'hours'), moment(day).add(18, 'hours'))) {
      acc = Object.assign(
        {},
        acc,
        { '16-18': [...acc['16-18'], rest] }
      )
    }
    if (moment(eventStart).isBetween(moment(day).add(18, 'hours'), moment(day).add(20, 'hours'))) {
      acc = Object.assign(
        {},
        acc,
        { '18-20': [...acc['18-20'], rest] }
      )
    }
    if (moment(eventStart).isBetween(moment(day).add(20, 'hours'), moment(day).add(22, 'hours'))) {
      acc = Object.assign(
        {},
        acc,
        { '20-22': [...acc['20-22'], rest] }
      )
    }
    if (moment(eventStart).isBetween(moment(day).add(22, 'hours'), moment(day).add(24, 'hours'))) {
      acc = Object.assign(
        {},
        acc,
        { '22-24': [...acc['22-24'], rest] }
      )
    }

    return acc
  }, {
    '8-10': [],
    '10-12': [],
    '12-14': [],
    '14-16': [],
    '16-18': [],
    '18-20': [],
    '20-22': [],
    '22-24': []
  })
  console.log(res)
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.20.1/moment.min.js"></script>

【问题讨论】:

  • 您的问题中没有预期的输出(如果我没有遗漏任何内容)。
  • 已编辑,对你有用吗?
  • 这不是关于什么对我有用,而是关于将接受提议的解决方案的明确和直接的标准。到目前为止,将示例数据转换为具有空 (?) 数组作为其属性的对象的逻辑尚不清楚(至少对我而言)。
  • 是否应该忽略其余时间 (0-8)?
  • 更新了问题。现在可能会忽略 0-8 范围

标签: javascript arrays momentjs lodash


【解决方案1】:

您可以使用 lodash 的 _.groupBy() 并通过从 eventStart 创建日期、向下舍入到最接近的偶数小时 (start) 并返回 start - start + 2 的范围来生成密钥:

const data = [{"data":42986084,"eventStart":1575621000000},
{"data":43729858,"eventStart":1575626400000},{"data":43727728,"eventStart":1575627000000}];

const result = _.groupBy(data, o => {
  const hour = new Date(o.eventStart).getHours(); // get the hour
  const start = hour - hour % 2; // normalize to the closest even hour
  
  return `${start}-${start + 2}`; // get the key
});

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>

同样的想法使用Array.reduce():

const data = [{"data":42986084,"eventStart":1575621000000},
{"data":43729858,"eventStart":1575626400000},{"data":43727728,"eventStart":1575627000000}];

const createRangeKey = eventStart => {
  const hour = new Date(eventStart).getHours(); // get the hour 
  const start = hour - hour % 2; // normalize to the closest even hour
  
  return `${start}-${start + 2}`; // get the key
};

const result = data.reduce((r, o) => {
  const key = createRangeKey(o.eventStart); // get the key
  
  if(!r[key]) r[key] = []; // init if not existing on the object
  
  r[key].push(o); // add the object to the key
  
  return r;
}, {});

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

如果您需要过滤掉不在 8-24 范围内的小时,您可以检查 start 是否小于 8。在此示例中,{"data":"ignore","eventStart": 1575669600000} 将被忽略。

const data = [{"data":42986084,"eventStart":1575621000000},
{"data":43729858,"eventStart":1575626400000},{"data":43727728,"eventStart":1575627000000}, {"data":"ignore","eventStart": 1575669600000}];

const result = data.reduce((r, o) => {
  const hour = new Date(o.eventStart).getHours(); // get the hour
  
  const start = hour - hour % 2; // normalize to the closest even hour
  
  if(start < 8) return r;
  
  const key = `${start}-${start + 2}`; // get the key
  
  if(!r[key]) r[key] = []; // init if not existing on the object
  
  r[key].push(o); // add the object to the key
  
  return r;
}, {});

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

【讨论】:

  • 只有我选择这个解决方案。遇到1575669600000 时,它不属于 24 小时格式
  • 这是一天的开始 - 0-2。结束是22-24。您的原始代码会忽略它。 groupBy 完成后,您可以选择所需的密钥。使用reduce,您可以过滤8 以下的所有内容。我添加了一个reduce 解决方案来演示。
  • 我的意思实际上是 24-26 组。是的,0-2 在那里,但 24-46 也在那里。仅供参考
  • 我刚刚意识到可能存在一些与时区相关的混淆......我所指的 eventStart 描述的是 23:00(晚上 11 点)
  • 刚刚也想通了。删除了小时的 + 1。
猜你喜欢
  • 2015-10-16
  • 1970-01-01
  • 1970-01-01
  • 2019-12-28
  • 1970-01-01
  • 2016-09-23
  • 1970-01-01
  • 1970-01-01
  • 2013-10-20
相关资源
最近更新 更多