你是否想过在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!
- 备注:机翻+个人粗略理解,如有不妥之处望指正。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。