按月份对数组和日期中的总值进行排序-Angular

时间:2020-03-06 07:15:56

标签: javascript angular typescript angular8

我有这种类型的json数据,我需要在给定日期按月对这些数据进行排序,并计算总值。

[
{
    "value": "123",
    "date": "01/01/2020"
},
{
    "value": "342",
    "date": "12/01/2020"
},
{
    "value": "432",
    "date": "23/01/2020"
},
{
    "value": "123",
    "date": "01/02/2020"
},
{
    "value": "123",
    "date": "01/01/2020"
},
{
    "value": "322",
    "date": "16/02/2020"
},
{
    "value": "643",
    "date": "26/02/2020"
}
]

我想在新数组中对像这样的新数据进行排序

[
 {
  "value": "1020", // total count of values
  "date": "Jan" // month in string
 },
 {
  "value": "1088", // total count of values
  "date": "Feb" // month in string
 }
]

我正在使用moment.js转换日期

预先感谢

2 个答案:

答案 0 :(得分:3)

const data = [{"value":123,"date":'01/01/2020'},{"value":342,"date":'12/01/2020'},{"value":432,"date":'23/01/2020'},{"value":123,"date":'01/02/2020'},{"value":123,"date":'01/01/2020'},{"value":322,"date":'16/02/2020'},{"value":643,"date":'26/02/2020'}];
const toDate = str => new Date(str.replace(/^(\d+)\/(\d+)\/(\d+)$/, "$2/$1/$3"));
const month = ['JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC'];
const map = data.reduce((a,b) => {
  const m = toDate(b.date).getMonth();
  a[m] = a[m] ? +a[m]+b.value : +b.value;
  return a;
}, {});
const res = Object.entries(map).map(([key, value]) => ({value, date: month[+key]}))
console.log(res)

答案 1 :(得分:2)

所以您有一个输入数组,格式为:

[
  { 
    date: "dd/mm/yyyy",
    value: number
  }
]

您想将其转换为一组分组对象:

[
  {
    month: "MMM",
    value: SUM(Values in month)
  }
]

这里的关键部分将是reduce数组函数和Map对象。

创建月份地图

使用reduce函数创建月份和总计值的映射。您可以遍历数组一次,然后将值保存到地图中,并随时更新值。

const map = this.data.reduce((map, current) => {
  const month = this.getMonth(current.date);
  const key = month.toISOString();
  if (!map.has(key)) {        
    map.set(key, 0);
  }      

  map.set(key, map.get(key) + current.value);
  return map;
}, new Map<string, number>());

this.getMonth(date)是一些映射功能。我使用的是正则表达式,但是如果您愿意,可以将其替换为瞬间。

private getMonth(dateString: string): Date {    
  const dateRegex = /(\d{2})\/(\d{2})\/(\d{4})/;
  const match = dateRegex.exec(dateString);

  return new Date(
    parseInt(match[3]),
    parseInt(match[2]) - 1,
    1
  );
}

排序月份

接下来,您可以根据在上一步中创建的地图创建一个按月排序的数组。密钥是ISO字符串,因此请使用字符串比较进行排序。

const months = Array.from(map.keys())
  .sort((a, b) => a.localeCompare(b));

映射结果

现在,您可以使用map函数将排序后的月份映射到最终输出。

months.map(x => ({
  month: formatDate(x, 'MMM', 'en-US'),
  value: map.get(x)
}));    

我在这里使用formatDate中的'@angular/common'函数。这是注入DatePipe的现代替代方法。我使用en-US语言环境,因为开箱即用的语言支持。您还可以使用力矩。

演示:https://stackblitz.com/edit/angular-sc6ktd