You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

不使用Lodash如何按对象键分组JavaScript对象数组?

对象数组按指定键分组的解决方案

你的现有代码其实已经完成了核心的分组逻辑,但返回的是以分组键值为属性名的对象(比如{ fruit: [...], meat: [...] }),和你期望的数组结构不符。只需要在现有逻辑基础上做一步格式转换就能得到目标结果。

修改后的完整代码

const grouper = key => array => 
    // 先按原逻辑分组得到对象,再转成目标数组结构
    Object.entries(array.reduce((acc, val) => {
        const property = val[key];
        acc[property] = acc[property] || [];
        acc[property].push(val);
        return acc;
    }, {})).map(([type, foods]) => ({ type, foods }))

代码拆解说明

  1. reduce分组:和你原来的代码逻辑一样,把数组按指定的key(这里是type)分组,得到一个键为分组值、值为对应元素数组的对象。
  2. Object.entries转换:把分组后的对象拆成键值对数组,比如变成[ ['fruit', [苹果,香蕉]], ['meat', [鸟,牛]], ['drinks', [啤酒]] ]。
  3. map结构转换:把每个键值对映射成你需要的{ type: 分组值, foods: 元素数组 }格式。

测试示例

代入你提供的foods数组测试:

const foods = [
  {id: 1, title: 'apple', type: 'fruit'},
  {id: 2, title: 'banana', type: 'fruit'},
  {id: 3, title: 'bird', type: 'meat'},
  {id: 4, title: 'beer', type: 'drinks'},
  {id: 5, title: 'cow', type: 'meat'},
]

const groupByType = grouper('type')
console.log(groupByType(foods))

输出结果完全匹配你期望的foodTypes格式。

可选:保证分组顺序(兼容老环境)

ES6+规范中普通对象会保留属性的插入顺序,但如果需要兼容更老的环境,或者要严格保证分组顺序和原数组中分组值首次出现的顺序一致,可以用Map代替普通对象存储分组结果:

const grouper = key => array => 
    Array.from(array.reduce((acc, val) => {
        const property = val[key];
        if (!acc.has(property)) {
            acc.set(property, []);
        }
        acc.get(property).push(val);
        return acc;
    }, new Map()).entries()).map(([type, foods]) => ({ type, foods }))

Map会严格按照键的插入顺序存储,兼容性更强。

内容的提问来源于stack exchange,提问作者Andrew

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 03:35:25