【问题标题】:Sum each row in object group by row逐行求和对象组中的每一行
【发布时间】:2018-05-27 07:40:11
【问题描述】:

我需要对minutesseconds_left 求和,并按id_project 分组。

0: {id_project: 2, minutes: 12, seconds_left: NaN}
1: {id_project: 3, minutes: 15, seconds_left: 11}
2: {id_project: 4, minutes: 0, seconds_left: 11}
3: {id_project: 5, minutes: 0, seconds_left: 2}
4: {id_project: 0, minutes: 0, seconds_left: NaN}
5: {id_project: 1, minutes: 0, seconds_left: NaN}
6: {id_project: 4, minutes: 200, seconds_left: 6}
7: {id_project: 6, minutes: 43, seconds_left: NaN}
8: {id_project: 5, minutes: 100, seconds_left: NaN}
9: {id_project: 2, minutes: 123, seconds_left: NaN}
10: {id_project: 3, minutes: 454, seconds_left: NaN}
11: {id_project: 2, minutes: 89, seconds_left: NaN}
12: {id_project: 5, minutes: 23, seconds_left: NaN}
13: {id_project: 4, minutes: 0, seconds_left: NaN}
14: {id_project: 4, minutes: 11, seconds_left: NaN}
15: {id_project: 3, minutes: 66, seconds_left: NaN}
16: {id_project: 1, minutes: 676, seconds_left: NaN}

我想到了 map & reduce,但我做不到。

我的问题有什么解决办法吗?

感谢您的回答:)

【问题讨论】:

    标签: javascript arrays reactjs ecmascript-6


    【解决方案1】:

    首先在执行之前放弃NaN 或将它们转换为0,否则算术都将具有NaN 值。 现在这就是我所做的:我创建了一个函数来将您的数组映射到一个具有唯一项目 ID 的新对象中,其中每个对象都有分钟和秒的总和:

    var arr = [
        { id_project: 2, minutes: 12, seconds_left: 1 },
        { id_project: 3, minutes: 15, seconds_left: 11 },
        { id_project: 4, minutes: 0, seconds_left: 11 },
        { id_project: 5, minutes: 0, seconds_left: 2 },
        { id_project: 0, minutes: 0, seconds_left: 2 },
        { id_project: 1, minutes: 0, seconds_left: 3 },
        { id_project: 4, minutes: 200, seconds_left: 6 },
        { id_project: 6, minutes: 43, seconds_left: 3 },
        { id_project: 5, minutes: 100, seconds_left: 3 },
        { id_project: 2, minutes: 123, seconds_left: 10 },
        { id_project: 3, minutes: 454, seconds_left: 2 },
        { id_project: 2, minutes: 89, seconds_left: 2 },
        { id_project: 5, minutes: 23, seconds_left: 3 },
        { id_project: 4, minutes: 0, seconds_left: 4 },
        { id_project: 3, minutes: 66, seconds_left: 5 },
        { id_project: 1, minutes: 676, seconds_left: 5 }
    ];
    
    var _flatten = function (arr) {
        var struct = {}; // We'll use a new flattened structure.
        var len = arr.length;
        for (var i = 0; i < len; i++) {
            var pID = arr[i].id_project;
            if (undefined !== struct[pID] && null !== struct[pID]) {
                // Already assigned. Sum minutes and seconds to already existing values.
                struct[pID].sum =
                    struct[pID].sum +
                    (arr[i].minutes * 60) +
                    arr[i].seconds_left;
            }
            else {
                // Current project ID has not been assigne to new structure. Assign.
                struct[pID] = { sum: (arr[i].minutes * 60) + arr[i].seconds_left };
            }
        }
        return struct;
    }
    

    输出(总和以秒为单位):

    _flatten(arr);
    
    0 : {sum: 2}
    1 : {sum: 40568}
    2 : {sum: 13453}
    3 : {sum: 32118}
    4 : {sum: 12021}
    5 : {sum: 7388}
    6 : {sum: 2583}
    

    【讨论】:

    • 很高兴听到:)
    • 一分钟是 60 秒,所以应该是:(arr[i].minutes*60) + arr[i].seconds_left;
    【解决方案2】:

    您可以将哈希表作为对具有相同 id_project 的对象的引用,并收集结果的所有值。

    var array = [{ id_project: 2, minutes: 12, seconds_left: NaN }, { id_project: 3, minutes: 15, seconds_left: 11 }, { id_project: 4, minutes: 0, seconds_left: 11 }, { id_project: 5, minutes: 0, seconds_left: 2 }, { id_project: 0, minutes: 0, seconds_left: NaN }, { id_project: 1, minutes: 0, seconds_left: NaN }, { id_project: 4, minutes: 200, seconds_left: 6 }, { id_project: 6, minutes: 43, seconds_left: NaN }, { id_project: 5, minutes: 100, seconds_left: NaN }, { id_project: 2, minutes: 123, seconds_left: NaN }, { id_project: 3, minutes: 454, seconds_left: NaN }, { id_project: 2, minutes: 89, seconds_left: NaN }, { id_project: 5, minutes: 23, seconds_left: NaN }, { id_project: 4, minutes: 0, seconds_left: NaN }, { id_project: 4, minutes: 11, seconds_left: NaN }, { id_project: 3, minutes: 66, seconds_left: NaN }, { id_project: 1, minutes: 676, seconds_left: NaN }],
        temp = {},
        result = [];
    
    array.forEach(function (o) {
        if (!temp[o.id_project]) {
            temp[o.id_project] = { id_project: o.id_project, minutes: 0, seconds_left: 0 };
            result.push(temp[o.id_project]);
        }
        temp[o.id_project].minutes += o.minutes || 0;
        temp[o.id_project].seconds_left += o.seconds_left || 0;
    });
    
    console.log(result);
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    【讨论】:

      【解决方案3】:

      如果您可以遍历此数组,请创建一个包含数组总和的新对象

      类似的东西

      var myArray = [{id_project: 2, minutes: 12, seconds_left: 30},{id_project: 2, minutes: 12, seconds_left: 50},{id_project: 3, minutes: 12, seconds_left: 12}]
      var result = {};
      myArray.forEach(function (element) {
        if (!result.hasOwnProperty(element.id_project))
          result[element.id_project] = {minutes : 0, seconds_left : 0};
        result[element.id_project].minutes += element.minutes;
        result[element.id_project].seconds_left += element.seconds_left;
      });
          
      console.log(result);

      【讨论】:

      • 不错,但原始数据集有 NaN 值,您应该先将它们设置为 0。
      【解决方案4】:

      以下内容可以满足您的要求,您可以使用 map 和 reduce。我只使用 map 将 NaN 替换为 0 并减少两次,一次获取总秒数,一次创建小时、分钟、秒对象:

      var tmpTotal = [
        {id_project: 2, minutes: 12, seconds_left: NaN}
        ,{id_project: 3, minutes: 15, seconds_left: 11}
        ,{id_project: 4, minutes: 0, seconds_left: 11}
        ,{id_project: 5, minutes: 0, seconds_left: 2}
        ,{id_project: 0, minutes: 0, seconds_left: NaN}
        ,{id_project: 1, minutes: 0, seconds_left: NaN}
        ,{id_project: 4, minutes: 200, seconds_left: 6}
        ,{id_project: 6, minutes: 43, seconds_left: NaN}
        ,{id_project: 5, minutes: 100, seconds_left: NaN}
        ,{id_project: 2, minutes: 123, seconds_left: NaN}
        ,{id_project: 3, minutes: 454, seconds_left: NaN}
        ,{id_project: 2, minutes: 89, seconds_left: NaN}
        ,{id_project: 5, minutes: 23, seconds_left: NaN}
        ,{id_project: 4, minutes: 0, seconds_left: NaN}
        ,{id_project: 4, minutes: 11, seconds_left: NaN}
        ,{id_project: 3, minutes: 66, seconds_left: NaN}
        ,{id_project: 1, minutes: 676, seconds_left: NaN}
      ]
      .map(//set seconds_left to 0 when NaN
        item=>
          isNaN(item.seconds_left)
            ? Object.assign({},item,{seconds_left:0})
            : item
      )
      .reduce(//group totals by id
        (acc,item)=>{
          acc[item.id_project]=acc[item.id_project] || {sum:0};
          acc[item.id_project].sum = 
            acc[item.id_project].sum + item.minutes * 60;
          acc[item.id_project].sum = 
            acc[item.id_project].sum + item.seconds_left;
          return acc;
        }
        ,{}
      );
      console.log(
        JSON.stringify(
          Object.keys(tmpTotal)//create hours,minutes,seconds from sum object
          .reduce(
            (acc,key)=>{
              acc[key] = {
                hours: Math.floor(tmpTotal[key].sum/3600),
                minutes: Math.floor((tmpTotal[key].sum%3600)/60),
                seconds: tmpTotal[key].sum%60
              }
              return acc;
            }
            ,{}
          )
          ,undefined
          ,2
        )
      );

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-07-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-08-12
        • 1970-01-01
        • 2020-04-03
        相关资源
        最近更新 更多