共计 1886 个字符,预计需要花费 5 分钟才能阅读完成。
你是否想过在 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!
- 备注:机翻 + 集体粗略了解,如有不妥之处望斧正。