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

将JS对象数组转为指定键分组对象:实现方法与工具推荐

刚好之前做过类似的需求,给你分享两种优雅的实现方式——原生JS手写和用Lodash简化,都能高效满足你的需求:

原生JS实现(无依赖)

核心思路是用Array.prototype.reduce遍历目标键数组,对每个键提取所有对象的对应值,再根据去重参数处理,最后组装成结果对象。这种方式不需要额外依赖,性能也很可观:

function groupByKeys(arr, keys, { unique = false } = {}) {
  return keys.reduce((result, key) => {
    // 提取所有对应键的值,可选过滤掉undefined/null(避免无效值混入)
    let values = arr.map(item => item[key]).filter(val => val != null);
    
    // 处理去重:用Set实现高效去重(仅对基础类型有效)
    if (unique) {
      values = [...new Set(values)];
    }
    
    result[key] = values;
    return result;
  }, {});
}

使用示例

const testData = [
  { id: 1, category: 'fruit', name: 'apple' },
  { id: 2, category: 'fruit', name: 'banana' },
  { id: 3, category: 'vegetable', name: 'apple' },
  { id: 4, category: 'fruit', name: 'apple' }
];

// 不去重的情况
console.log(groupByKeys(testData, ['category', 'name']));
// 输出:{ category: ['fruit', 'fruit', 'vegetable', 'fruit'], name: ['apple', 'banana', 'apple', 'apple'] }

// 去重的情况
console.log(groupByKeys(testData, ['category', 'name'], { unique: true }));
// 输出:{ category: ['fruit', 'vegetable'], name: ['apple', 'banana'] }
Lodash/Underscore简化方案

如果你已经在用Lodash或者Underscore,那可以用它们的工具函数大幅简化代码,可读性拉满:

Lodash版本

import _ from 'lodash';

function groupByKeysLodash(arr, keys, { unique = false } = {}) {
  return _.fromPairs(
    keys.map(key => [
      key,
      // 提取值 + 可选去重
      unique ? _.uniq(_.map(arr, key)) : _.map(arr, key)
    ])
  );
}

Underscore版本(和Lodash逻辑几乎一致)

import _ from 'underscore';

function groupByKeysUnderscore(arr, keys, { unique = false } = {}) {
  return _.object(
    keys.map(key => [
      key,
      unique ? _.uniq(_.pluck(arr, key)) : _.pluck(arr, key)
    ])
  );
}

这里用到的_.fromPairs(Lodash)/_.object(Underscore)负责把键值对数组转成对象,_.map/_.pluck提取对应键的值,_.uniq处理去重,一行核心逻辑就能搞定。

额外注意点
  • 如果需要对**复杂类型(比如对象、数组)**去重,原生的Set就失效了,这时候可以用Lodash的_.uniqWith配合_.isEqual:
    // 复杂类型去重示例(Lodash)
    unique ? _.uniqWith(_.map(arr, key), _.isEqual) : _.map(arr, key)
    
  • 如果希望保留undefined或null值,只需要去掉原生实现里的.filter(val => val != null)即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 06:59:29