JavaScript按对象数组属性分组:属性为数组类型时的实现问题
解决多类别分组需求的方案
确实,Array.groupBy的设计逻辑是给每个元素分配唯一的分组键,没法直接处理一个元素属于多个分类的场景。这种情况下,我们可以用Array.reduce来手动实现多分组的逻辑,步骤很清晰:
- 先初始化一个空对象作为最终的分组容器
- 遍历输入数组里的每一项
- 对当前项的
categoryLookup数组逐个遍历,取出每个分类的category_name作为分组键 - 如果容器里还没有这个分组键,就先创建一个空数组来存放对应项
- 把当前项添加到这个分组的数组里
- 最后返回这个分组容器
下面是针对你给出的示例输入写的完整代码:
const input = [ { "tool_id": "4-19de-454673d9-9ef5-4545", "somekey": "Parent Item 2", "categoryLookup": [ { "category_name": "New Item" } ] }, { "tool_id": "be7ea707-19de-43d9-9ef1-d4a3ff79f77a", "somekey": "Parent Item", "categoryLookup": [ { "category_name": "My Cat" }, { "category_name": "Something Else" } ] } ]; const groupedResult = input.reduce((acc, item) => { // 遍历当前项的所有分类条目 item.categoryLookup.forEach(category => { const groupKey = category.category_name; // 若分组不存在则初始化空数组 if (!acc[groupKey]) { acc[groupKey] = []; } // 将当前项加入对应分组 acc[groupKey].push(item); }); return acc; }, {}); console.log(groupedResult);
运行这段代码后,就能得到你想要的结果:每个分类下都会包含所有属于它的元素,比如"Parent Item"会同时出现在"My Cat"和"Something Else"两个分组中。
如果你的场景里可能出现categoryLookup包含重复分类名的情况,可以在push之前加个判断,避免同一元素重复加入同一个分组,比如:
if (!acc[groupKey].includes(item)) { acc[groupKey].push(item); }
不过从你的示例来看,应该不需要额外处理这种情况。
内容的提问来源于stack exchange,提问作者Squiggs.
相关产品推荐
相关产品推荐

