【问题标题】:How to group array of dates by year and subtract last value - first value?如何按年份对日期数组进行分组并减去最后一个值 - 第一个值?
【发布时间】:2021-12-11 18:01:09
【问题描述】:

我有日期数组,我想按年份对日期进行分组并减去最后一个值 - 第一个值。例如,我有以下数组:

const data = [
  { x: "2021-10-17T14:38:45.540Z", y: 2 },
  { x: "2021-10-17T13:38:45.540Z", y: 2 },
  { x: "2021-09-16T14:36:46.540Z", y: 1 },
  { x: "2021-01-04T14:35:46.540Z", y: 2 },
  { x: "2021-01-01T14:30:46.540Z", y: 1 },
  { x: "2020-02-01T06:28:47.520Z", y: 12 },
  { x: "2020-02-01T07:28:47.520Z", y: 12 },
  { x: "2019-04-13T10:19:20.034Z", y: 20 },
  { x: "2018-01-01T09:09:19.134Z", y: 4 },
  { x: "2017-01-01T12:09:19.034Z", y: 11 },
  { x: "2016-01-02T12:10:20.034Z", y: 24 },
  { x: "2016-01-02T11:10:20.034Z", y: 14 }
];

这是我尝试过的Group array of object by year and subtract the last value - the first value

我得到了对这些值求和的结果:

 [
  {
    "value": 8,
    "label": "2021"
  },
  {
    "value": 24,
    "label": "2020"
  },
  {
    "value": 20,
    "label": "2019"
  },
  {
    "value": 4,
    "label": "2018"
  },
  {
    "value": 11,
    "label": "2017"
  },
  {
    "value": 38,
    "label": "2016"
  }
]

一年的预期输出(值 = 最后一个值 - 第一个值):

 [
  {
    "value": 1,
    "label": "2021"
  },
  {
    "value": 0,
    "label": "2020"
  },
  {
    "value": 20,
    "label": "2019"
  },
  {
    "value": 4,
    "label": "2018"
  },
  {
    "value": 11,
    "label": "2017"
  },
  {
    "value": 10,
    "label": "2016"
  }
]

这是按年分组功能:

function group_by_year(arr) {
  return Object.values(
    arr.reduce((a, { x: date_string, y: value }) => {
      const { year } = get_date_parts(date_string);
      if (a[year] === undefined) {
        a[year] = { value: 0, label: year };
      }
      a[year].value += value; // the problem (lastValue - firstValue)

      return a;
    }, {})
  );
}

问题是如何将这一行a[year].value += value;改为a[year].value = lastValue - firstValue;

【问题讨论】:

    标签: javascript arrays date array-reduce


    【解决方案1】:

    在累加器中,您只是将数组中的值相加。这将产生一年的总价值。

    我使用了以下逻辑。

    • 每年保持firstValuelastValuelabeloccurance 反对。
    • firstValue 保存当年的第一次出现值。
    • lastValue 保存当年的最后一次出现值。
    • label年值
    • occurance 数组中每年的计数。

    Array.reduce得到的累加结果,运行Array.map生成你想要的输出。它将是lastValue - firstValue。如果您只对没有符号的正差异感兴趣,请使用Math.abs

    工作小提琴

    const data = [{ x: "2021-10-17T14:38:45.540Z", y: 2 },{ x: "2021-10-17T13:38:45.540Z", y: 2 },{ x: "2021-09-16T14:36:46.540Z", y: 1 },{ x: "2021-01-04T14:35:46.540Z", y: 2 },{ x: "2021-01-01T14:30:46.540Z", y: 1 },{ x: "2020-02-01T06:28:47.520Z", y: 12 },{ x: "2020-02-01T07:28:47.520Z", y: 12 },{ x: "2019-04-13T10:19:20.034Z", y: 20 },{ x: "2018-01-01T09:09:19.134Z", y: 4 },{ x: "2017-01-01T12:09:19.034Z", y: 11 },{ x: "2016-01-02T12:10:20.034Z", y: 24 },{ x: "2016-01-02T11:10:20.034Z", y: 14 }];
    
    function get_date_parts(iso_string) {
      const [year, month, day, hr, min, sec] = iso_string.split(/\D/g);
      return { year, month, day, hr, min, sec };
    }
    
    function group_by_year(arr) {
      const grouppedYear = Object.values(
        arr.reduce((a, { x: date_string, y: value }) => {
          const { year } = get_date_parts(date_string);
          if (a[year] === undefined) {
            a[year] = {
              firstValue: value,
              lastValue: value,
              label: year,
              occurance: 1,
            };
          } else {
            a[year].lastValue = value;
            ++a[year].occurance;
          }
          return a;
        }, {})
      );
      const returnValue = grouppedYear.map(({firstValue, lastValue, label, occurance}) => ({value: occurance > 1 ? lastValue - firstValue : firstValue, label}))
      return returnValue;
    }
    const output = group_by_year(data);
    console.log(output)

    【讨论】:

    • 如何将groupedYear的[{x,y}]数据列表添加到returnValue中?我试过a[year].data = !a[year].data ? [].concat([{ x: date_string, y: value }]) : a[year].data.concat([{ x: date_string, y: value }]);,但它没有添加第一个值。总是缺少一个值。
    • mb,我错过了这一行。 if (a[year] === undefined) { a[year] = { data: [{ x: date_string, y: value }] //...}}
    • 是的,又来了。
    【解决方案2】:

    使用矩库可以将日期字符串提取到年份 moment("2021-10-17T14:38:45.540Z").format('YYYY') 准备好数组对象后,您可以简单地对数组进行排序并找到答案

    这里你必须制作单独的一组同年数据数组,然后第一个和最后一个索引可以简单地在 for 循环中找到

    【讨论】:

    • 考虑到project's status,您可能需要重新考虑建议使用它。
    • @Harsh Mendapara 我用momentjs试过,问题是有些年份没有显示。 stackoverflow.com/questions/69615993/… 可以使用array.reduce 来获取第一个值和最后一个值吗?我已经在 group_by_year 方法中对日期进行了分组。问题是如何将这一行 a[year].value += value; 更改为 a[year].value = lastValue - firstValue;
    猜你喜欢
    • 2021-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多