关于javascript:数组按类分组新方法ArrayprototypegroupBy

你是否想过在js中如何对数组正确地进行分组?让我猜猜,你是否对后果不太称心?

数组分组是一种很常见的操作,并有很多种实现办法,然而直到现在也没有原生办法并且所有实现的办法都有些…简短难懂?

咱们将会探讨如何进行分组并简化这所有。

Setup

items数组

const items = [
  {
    type: 'fruit',
    value: '🍎',
  },
  {
    type: 'fruit',
    value: '🍇',
  },
  {
    type: 'fruit',
    value: '🍊',
  },
  {
    type: 'vegetable',
    value: '🥦',
  },
  {
    type: 'vegetable',
    value: '🥕',
  },
  {
    type: 'vegetable',
    value: '🌶️',
  },
];

items数组基于type进行分组,失去的后果如下:

{
  "fruit": [
    {
      "type": "fruit",
      "value": "🍎"
    },
    {
      "type": "fruit",
      "value": "🍇"
    },
    {
      "type": "fruit",
      "value": "🍊"
    }
  ],
  "vegetable": [
    {
      "type": "vegetable",
      "value": "🥦"
    },
    {
      "type": "vegetable",
      "value": "🥕"
    },
    {
      "type": "vegetable",
      "value": "🌶️"
    }
  ]
}

之前的分组形式

如果你想看到最好的计划能够间接查看页面底部。

Reduce

应用Array.protoype.reduce,只管因为这种语法往往会导致难以了解,对于reducers的想法常常被弱化。

items.reduce(
  (acc, item) => ({
    ...acc,
    [item.type]: [...(acc[item.type] ?? []), item],
  }),
  {},
);

Edit:有些人提出应用{...spread}可能是 an anti-pattern 和 a bad idea,。因而让咱们提供另一个reduce的解决方案。

items.reduce((acc, item) => {
  if (acc[item.type]) {
    acc[item.type].push(item);
  } else {
    acc[item.type] = [item];
  }

  return acc;
}, {});

for…of 语法

const groupedBy = {};
for (const item of items) {
  if (groupedBy[item.type]) {
    groupedBy[item.type].push(item);
  } else {
    groupedBy[item.type] = [item];
  }
}

Filter

应用多个filter办法可能是最易读的计划,但它不是最优的。须要屡次过滤数组并且须要你分明地晓得每一个分组。

const groupedBy = {
  fruit: items.filter((item) => item.type === 'fruit'),
  vegetable: items.filter((item) => item.type === 'vegetable'),
};

Chaining pure functions

⚠️ Please don’t do this! This is purely for demonstration purposes.

如果咱们想应用函数式编程的同时防止reducers,很快就会显得很荒诞。甚至GitHub Copilot: Labs 也很难解释分明.

咱们想获取items所有的类型并将其转换为对象, 而后迭代对象的值,将值作为键,并应用过滤器按类型分组进行填充. 😵‍💫

Object.values({
  ...Array.from(new Set(items.map(({ type }) => type))),
}).map((type) => ({ [type]: items.filter((item) => item.type === type) }));

Array.prototype.groupBy

TC39 committee 正在介绍 数组分组提议 (⚠️ Stage 3). 🎉

从明天就开始应用它,须要为Array.prototype.groupBy办法提供一个符合规范的shim/polyfill: https://github.com/es-shims/A….
它应该也很快作为 stage-3 预设的一部分.

items.groupBy(({ type }) => type);

还有什么好说得,很简略不是吗?我曾经急不可待其随着ES2022一起公布,以及ts和浏览器的反对。

  • 原文:Array.prototype.groupBy to the rescue!
  • 备注:机翻+集体粗略了解,如有不妥之处望斧正。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理