【问题标题】:How to group objects and make calculations for each group of objects efficiently如何有效地对对象进行分组并为每组对象进行计算
【发布时间】:2019-05-15 10:54:30
【问题描述】:

我正在开发一个从 API 获取一些数据的 javascript 应用程序,这就是数据集的一些记录的样子:

    {eventAction: "area", sessionId: "20190515|04434531", timestamp: "15- 
    05-2019 10:56:28", duration: "45.665", nodeId: "1", …}
    {eventAction: "area", sessionId: "20190515|04434531", timestamp: "15-                                        
    05-2019 10:56:28", duration: "47.602", nodeId: "9", …}
    {eventAction: "area", sessionId: "20190515|04434531", timestamp: "15- 
    05-2019 10:56:28", duration: "5.287", nodeId: "12", …}
    {eventAction: "area", sessionId: "20190515|04434531", timestamp: "15- 
    05-2019 10:56:28", duration: "5.932", nodeId: "27", …}
    {eventAction: "area", sessionId: "20190515|04434531", timestamp: "15- 
    05-2019 10:56:28", duration: "56.918", nodeId: "9", …}

如您所见,它是一组对象,现在我要做的是,按 nodeId 对这组对象进行分组。所以我可以对每个nodeId进行计算。我想要每个 nodeId 的平均持续时间。但我真的不知道从哪里开始/如何有效地做到这一点。

我认为它必须使用一些过滤器/映射/减少,对吗?我还不能完全理解这一点

感谢您的问候

【问题讨论】:

  • 我假设您从 API 收到的数据以对象数组的形式返回?
  • 预期的输出应该是什么?
  • @KobanDavis 没错,一个对象数组

标签: javascript arrays json object


【解决方案1】:

您可以获取一个对象并存储每个nodeId 的总和、计数和平均值。

var data = [{ eventAction: "area", sessionId: "20190515|04434531", timestamp: "15-05-2019 10:56:28", duration: "45.665", nodeId: "1" }, { eventAction: "area", sessionId: "20190515|04434531", timestamp: "15-05-2019 10:56:28", duration: "47.602", nodeId: "9" }, { eventAction: "area", sessionId: "20190515|04434531", timestamp: "15-05-2019 10:56:28", duration: "5.287", nodeId: "12" }, { eventAction: "area", sessionId: "20190515|04434531", timestamp: "15-05-2019 10:56:28", duration: "5.932", nodeId: "27" }, { eventAction: "area", sessionId: "20190515|04434531", timestamp: "15-05-2019 10: 56: 28", duration: "56.918", nodeId: "9" }],
    result = data.reduce((r, { duration, nodeId }) => {
        r[nodeId] = r[nodeId] || { sum: 0, count: 0, average: 0 };
        r[nodeId].sum += +duration;
        r[nodeId].average = r[nodeId].sum / ++r[nodeId].count;
        return r;
    }, {});

console.log(result)

【讨论】:

    【解决方案2】:

    我相信这就是你想要的 - 使用 reduce:

    const data = [{eventAction: "area", sessionId: "20190515|04434531", timestamp: "15-05-2019 10:56:28", duration: "45.665", nodeId: "1"}, {eventAction: "area", sessionId: "20190515|04434531", timestamp: "15-05-2019-10:56:28", duration: "47.602", nodeId: "9"}, {eventAction: "area", sessionId: "20190515|04434531", timestamp: "15-05-2019 10:56:28", duration: "5.287", nodeId: "12"}, {eventAction: "area", sessionId: "20190515|04434531", timestamp: "15- 05-2019 10:56:28", duration: "5.932", nodeId: "27"}, {eventAction: "area", sessionId: "20190515|04434531", timestamp: "15-05-2019 10:56:28", duration: "56.918", nodeId: "9"}];
    
    const res = data.reduce((acc, curr) => {
      acc[curr.nodeId] = acc[curr.nodeId] ? acc[curr.nodeId].concat(curr) : [curr];
      return acc;
    }, {});
    
    console.log(res);
    .as-console-wrapper { max-height: 100% !important; top: auto; }

    【讨论】:

      【解决方案3】:

      使用reducenodeId 分组,并创建持续时间数组。然后你可以使用map 得到你的平均持续时间

      const input = [
      {eventAction: "area", sessionId: "20190515|04434531", timestamp: "15-05-2019 10:56:28", duration: "45.665", nodeId: "1"},
      {eventAction: "area", sessionId: "20190515|04434531", timestamp: "15-05-2019 10:56:28", duration: "47.602", nodeId: "9"},
      {eventAction: "area", sessionId: "20190515|04434531", timestamp: "15- 05-2019 10:56:28", duration: "5.287", nodeId: "12"},
      {eventAction: "area", sessionId: "20190515|04434531", timestamp: "15- 05-2019 10:56:28", duration: "5.932", nodeId: "27"},
      {eventAction: "area", sessionId: "20190515|04434531", timestamp: "15- 05-2019 10:56:28", duration: "56.918", nodeId: "9"}];
      
      const groupByNodeId = Object.values(input.reduce((accu, {nodeId, duration, ...rest}) => {
          if(!accu[nodeId]) {
              accu[nodeId] = {...rest, nodeId, durations : []};
          } 
          // console.log(accu[nodeId]);
          accu[nodeId].durations.push(Number(duration));
          return accu;
      }, {}));
      
      const getSum = (arr) => arr.reduce((accu, num) => accu+num);
      const output = groupByNodeId.map(({durations, ...rest}) => ({...rest, durationAvg: getSum(durations)/durations.length}));
      console.log(output);

      【讨论】:

        猜你喜欢
        • 2017-03-03
        • 2018-01-12
        • 2018-05-01
        • 1970-01-01
        • 2022-01-18
        相关资源
        最近更新 更多