按通用属性(日期)汇总对象数组

时间:2020-08-07 22:15:37

标签: javascript angular typescript

嗨,我有一个棱角分明的项目。

当前,我有一个名为historyArr的数组。它具有一些为期2天的统计数据,如下所示。

 [
  {
    "dateRange": "2020-07-01T16:00:00.000+0000",
    "total": 20,
    "delivered": 5,
    "undeliverable": 5,
    "expired": 5,
    "enroute": 5
  },
  {
    "dateRange": "2020-07-01T17:00:00.000+0000",
    "total": 50,
    "delivered": 10,
    "undeliverable": 15,
    "expired": 10,
    "enroute": 15
  },
  {
    "dateRange": "2020-07-01T18:00:00.000+0000",
    "total": 8,
    "delivered": 2,
    "undeliverable": 2,
    "expired": 2,
    "enroute": 2
  },
  {
    "dateRange": "2020-07-02T00:00:00.000+0000",
    "total": 160,
    "delivered": 40,
    "undeliverable": 40,
    "expired": 40,
    "enroute": 40
  },
  {
    "dateRange": "2020-07-02T01:00:00.000+0000",
    "total": 200,
    "delivered": 50,
    "undeliverable": 50,
    "expired": 50,
    "enroute": 50
  }
]

我想减少上面的数组,以便我希望每天进行统计求和。所以我想将上面的数组转换为下面的数组。我可以自由地使用moment.js库来解析日期。

[
  {
    "dateRange": "2020-07-01",
    "total": 78,
    "delivered": 17,
    "undeliverable": 22,
    "expired": 17,
    "enroute": 22
  },
  {
    "dateRange": "2020-07-02",
    "total": 360,
    "delivered": 90,
    "undeliverable": 90,
    "expired": 90,
    "enroute": 900
  }
] 
我知道这是一个难题。该项目以stackblitz上传

https://stackblitz.com/edit/angular-zqmdpy

https://angular-zqmdpy.stackblitz.io

https://stackblitz.com/edit/angular-zqmdpy?embed=1&file=src/app/app.component.html

非常感谢您的帮助 谢谢

3 个答案:

答案 0 :(得分:2)

这是一个想法,您应该怎么做,我对日期的所有正确格式都不太注意,您应该改进它,我创建了一个辅助变量,该变量不会发生变化,以便不更改原始数组

    ngOnInit() {
    var temp = {};
    var obj = null;
    
  this.arr = data;
  this.historyArr = this.arr['histogramDistributionbyCdrStatuses']; 
  this.historyArr.forEach(el=>{
      el.dateRange=moment(el.dateRange).format('YYYY-MM-DD')
  })
  let auxArr = JSON.parse(JSON.stringify(this.historyArr));

  for(var i=0; i < auxArr.length; i++) {
      obj=auxArr[i];

      if(!temp[obj.dateRange]) {
          temp[obj.dateRange] = obj;
      } else {
          temp[obj.dateRange].total += obj.total;
      }
    }
    var result = [];
    for (var prop in temp)
        result.push(temp[prop]);
    console.log(result)



  }

答案 1 :(得分:2)

您可以

  • 执行String.prototype.slice()以获得dateRange有意义的部分并将其用作密钥
  • 遍历您的源数组(例如,使用Array.prototype.reduce()
  • 并建立具有已分组/汇总的对象作为各自值的Map
  • 然后使用Map.prototype.values()将这些值提取到数组中
  • 假设除dateRange以外的所有属性都应汇总 ,您可以使用一些快捷方式来不对所有属性进行明确的硬编码:

const src = [{"dateRange":"2020-07-01T16:00:00.000+0000","total":20,"delivered":5,"undeliverable":5,"expired":5,"enroute":5},{"dateRange":"2020-07-01T17:00:00.000+0000","total":50,"delivered":10,"undeliverable":15,"expired":10,"enroute":15},{"dateRange":"2020-07-01T18:00:00.000+0000","total":8,"delivered":2,"undeliverable":2,"expired":2,"enroute":2},{"dateRange":"2020-07-02T00:00:00.000+0000","total":160,"delivered":40,"undeliverable":40,"expired":40,"enroute":40},{"dateRange":"2020-07-02T01:00:00.000+0000","total":200,"delivered":50,"undeliverable":50,"expired":50,"enroute":50}],

      result = [...src
        .reduce((acc, o) => {
          const key = o.dateRange.slice(0,10),
                group = acc.get(key)
          if(group){
            const { dateRange, ...rest } = o
            Object
              .keys(rest)
              .forEach(key => 
                group[key] = (group[key] || 0) + (o[key] || 0))
          } else {
            acc.set(key, {...o, dateRange: key})
          }          
          return acc
        }, new Map)
        .values()
     ]
     
console.log(result)
.as-console-wrapper{min-height:100%;}

答案 2 :(得分:2)

我遍历数组并从条目中获取日期。我看这个日期是否在帮助数组索引中。如果不是,那么我将使用该条目的属性创建一个新条目,并将其附加到结果中。否则,我将在结果数组中查找该索引,并将该元素的所有属性汇总到该条目中。

function transformArray( array ) {
    let result = [];
    let index = [];
    array.forEach(obj => {
        const  PROPERTIES = Object.keys(obj);
        PROPERTIES.splice(PROPERTIES.indexOf('dateRange'),1);
        let dat = obj.dateRange.substr(0,10);
        let resIndex = index.indexOf(dat);
        if ( resIndex == -1) {
            index.push(dat);
            let entry = { dateRange: dat}
            PROPERTIES.forEach (prop => entry[prop] = obj[prop] || 0);
            result.push(entry);
        } else {
            let entry = result[resIndex];
            PROPERTIES.forEach (prop => entry[prop] = (entry[prop] || 0) + (obj[prop] || 0));
        }
    });
    return result;
}

let historyArr = [
  {
    "dateRange": "2020-07-01T16:00:00.000+0000",
    "total": 20,
    "delivered": 5,
    "undeliverable": 5,
    "expired": 5,
    "enroute": 5
  },
  {
    "dateRange": "2020-07-01T17:00:00.000+0000",
    "total": 50,
    "delivered": 10,
    "undeliverable": 15,
    "expired": 10,
    "enroute": 15
  },
  {
    "dateRange": "2020-07-01T18:00:00.000+0000",
    "total": 8,
    "delivered": 2,
    "undeliverable": 2,
    "expired": 2,
    "enroute": 2
  },
  {
    "dateRange": "2020-07-02T00:00:00.000+0000",
    "total": 160,
    "delivered": 40,
    "undeliverable": 40,
    "expired": 40,
    "enroute": 40
  },
  {
    "dateRange": "2020-07-02T01:00:00.000+0000",
    "total": 200,
    "delivered": 50,
    "undeliverable": 50,
    "expired": 50,
    "enroute": 50
  }
];

console.log(transformArray(historyArr));