按年和月对数组进行分组

时间:2021-07-12 09:05:28

标签: javascript date

我想按年和月将一个包含事件的数组分组。我的数据如下所示:

const events = [
  {
    name: "event 1",
    year: 2021,
    month: 1,
  },
  {
    name: "event 2",
    year: 2021,
    month: 9,
  },
  {
    name: "event 3",
    year: 2021,
    month: 1,
  },
  {
    name: "event 4",
    year: 2022,
    month: 7,
  },
]

我的预期结果应该是这样的:

[
  {
    year: 2021,
    month: 1,
    events: [
      {
        name: "event 1"
      },
      {
        name: "event 3"
      }
    ]
  },
  {
    year: 2021,
    month: 9,
    events: [
      {
        name: "event 2"
      }
    ]
  }
]

这样做的最佳方法是什么?我发现了一些 stackoverflow 帖子,可以通过它的键值对数组进行分组,但这不是我想要的。

const groupBy = (array, key) => {
  return array.reduce((result, currentValue) => {
    // If an array already present for key, push it to the array. Else create an array and push the object
    (result[currentValue[key]] = result[currentValue[key]] || []).push(currentValue);
    // Return the current iteration `result` value, this will be taken as next iteration `result` value and accumulate
    return result;
  }, {}); // empty object is the initial value for result object
};

const groupedByYear = groupBy(events, 'year');

2 个答案:

答案 0 :(得分:1)

您可以使用 reduceObject.values

const events = [
  {
    name: "event 1",
    year: 2021,
    month: 1,
  },
  {
    name: "event 2",
    year: 2021,
    month: 9,
  },
  {
    name: "event 3",
    year: 2021,
    month: 1,
  },
];

const result = Object.values(events.reduce( (acc,evt) => {
    const key = `${evt.year}-${evt.month}`;
    if(!acc[key]) {
      acc[key] = {year: evt.year, month: evt.month, events:[]}
    }
    acc[key].events.push( {name:evt.name} );
    return acc;
},{}));

console.log(result);

答案 1 :(得分:0)

您可以采用动态方法,对需要的属性使用组合键进行分组。

然后删除所有grouing键并推送一个没有不需要的属性的新对象。

const
    events = [{ name: "event 1", year: 2021, month: 1 }, { name: "event 2", year: 2021, month: 9 }, { name: "event 3",  year: 2021, month: 1 }],
    keys = ['year', 'month'],
    result = Object.values(events.reduce((r, o) => {
        let value,
            key = keys.map(k => o[k]).join('|');

        if (!r[key]) r[key] = { ...Object.fromEntries(keys.map(k => [k, o[k]])), events: [] };
        
        r[key].events.push(keys.reduce((t, k) => (({ [k]: value, ...t } = t), t), o));
        return r;
    }, {}));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }