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

如何高效实现JavaScript对象数组按type字段唯一值分组并生成指定统计结果数组

问题描述

我有一个对象数组,示例如下:

const data = [ 
  {'name': 'apple', 'type': 'fruit', 'quantity': 5}, 
  {'name': 'orange', 'type': 'fruit', 'quantity': 8}, 
  {'name': 'broccoli', 'type': 'vegetable', 'quantity': 5}, 
  ... 
]

需求是:针对type字段的每一个唯一值,返回一个包含分组统计信息的结果数组,格式如下:

output = [ 
  { 'field': 'fruit', 'count': 2, 'minQuantity': 5, 'maxQuantity': 8, 'values': ['apple', 'orange'] }, 
  { 'field': 'vegetable', 'count': 1, 'minQuantity': 5, 'maxQuantity': 5, 'values': ['broccoli'] } 
]

我目前尝试的代码只实现了部分功能,而且感觉效率不够高,代码如下:

let returnData = []; 
let fieldSet = new Set(data.map(a => a.type)); 
let fields = Array.from(fieldSet); 
for (var i = 0; i < fields.length; i++) { 
  let objs = data.filter(obj => { 
    return obj.type === fields[i] 
  }) 
  returnData.push({ field: fields[i], count: objs.length })
}

请问有没有简单且高效的实现方式可以完善需求?

解决方案

当然有!你当前的实现虽然能完成count的统计,但存在两个问题:一是没实现minQuantity、maxQuantity和values的需求;二是效率偏低——因为每次循环都要重新过滤整个数组,时间复杂度是O(n*m)(n是数据总长度,m是唯一type的数量),数据量大的时候性能会打折扣。

更高效的方式是只遍历一次数组,用Array.reduce()完成分组和所有统计逻辑,时间复杂度直接降到O(n),简单又高效。完整实现代码如下:

const data = [
  {'name': 'apple', 'type': 'fruit', 'quantity': 5},
  {'name': 'orange', 'type': 'fruit', 'quantity': 8},
  {'name': 'broccoli', 'type': 'vegetable', 'quantity': 5},
  // 可添加更多测试数据
];

const output = Object.values(data.reduce((acc, item) => {
  // 若当前type未在累加器中,初始化分组结构
  if (!acc[item.type]) {
    acc[item.type] = {
      field: item.type,
      count: 0,
      minQuantity: Infinity, // 初始设为无穷大,确保第一个元素能覆盖它
      maxQuantity: -Infinity, // 初始设为负无穷,确保第一个元素能覆盖它
      values: []
    };
  }

  // 更新当前分组的统计数据
  const group = acc[item.type];
  group.count++;
  group.minQuantity = Math.min(group.minQuantity, item.quantity);
  group.maxQuantity = Math.max(group.maxQuantity, item.quantity);
  group.values.push(item.name);

  return acc;
}, {}));

console.log(output);

代码逻辑解释:

  1. reduce遍历与分组:用reduce遍历数组,累加器acc是一个以type为键的临时对象,用来存储每个分组的统计信息
  2. 初始化分组结构:遇到新的type时,初始化对应的分组对象,其中minQuantity和maxQuantity的初始值设置是关键——用无穷大/负无穷能确保第一个元素的数量正确成为初始的最小/最大值
  3. 更新统计数据:对每个元素,更新对应分组的计数、最小/最大数量,并将元素名称加入values数组
  4. 转换为目标数组:最后用Object.values()把临时对象的所有值提取出来,就得到了符合需求的结果数组

这种方式不仅代码更简洁,而且只需要遍历一次数据,在数据量较大时的性能优势会非常明显。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 21:22:32