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

JavaScript如何按嵌套属性对对象数组进行分组?

实现按日期、名称分组并合并物品数量

原始数据

[
  {
    "date": "08/08/2022",
    "name": "Swordsman",
    "items": [
      {
        "item_id": 1,
        "item": {
          "item_name": "Item 1",
        },
        "count": 1
      }
    ]
  },
  {
    "date": "08/08/2022",
    "name": "Swordsman",
    "items": [
      {
        "item_id": 1,
        "item": {
          "item_name": "Item 1",
        },
        "count": 2
      },
      {
        "item_id": 2,
        "item": {
          "item_name": "Item 2",
        },
        "count": 1
      }
    ]
  }
]

需求说明

需要按date和name进行分组,合并同一分组内相同item_id的物品的count值,最终输出结构如下:

[
  {
    "date": "08/08/2022",
    "name": "Swordsman",
    "items": [
      {
        "item_id": 1,
        "name": "Item 1",
        "count": 3
      },
      {
        "item_id": 2,
        "name": "Item 2",
        "count": 1
      }
    ]
  }
]

当存在同一date不同name的情况时,需按date和name分别分组。

尝试过的代码(未得到预期结果)

const groups = data.reduce((groups, data) => {
  const date = data.date;
  if (!groups[date]) {
    groups[date] = [];
  }
  
  groups[date].push(data);
  return groups;
}, {});

const groupArrays = Object.keys(groups).map((date) => {
  return {
    date,
    items: groups[date]
  };
});

解决方案

方法一:原生JavaScript实现

核心思路是用date + name作为分组的唯一键,先聚合所有同组数据,再对分组内的物品按item_id合并count:

const data = [/* 你的原始数据 */];

const result = Object.values(data.reduce((acc, current) => {
  // 生成唯一分组标识:日期+名称
  const groupKey = `${current.date}_${current.name}`;
  
  if (!acc[groupKey]) {
    // 初始化分组结构
    acc[groupKey] = {
      date: current.date,
      name: current.name,
      items: {} // 用对象暂存物品,便于按item_id快速查找
    };
  }
  
  // 遍历当前项的物品,累加count
  current.items.forEach(item => {
    const itemKey = item.item_id;
    if (!acc[groupKey].items[itemKey]) {
      acc[groupKey].items[itemKey] = {
        item_id: item.item_id,
        name: item.item.item_name,
        count: 0
      };
    }
    acc[groupKey].items[itemKey].count += item.count;
  });
  
  return acc;
}, {})).map(group => {
  // 将物品对象转为数组格式
  group.items = Object.values(group.items);
  return group;
});

console.log(result);

方法二:使用Lodash实现

借助_.groupBy完成基础分组,再通过数组方法合并物品的count值:

const _ = require('lodash');

const data = [/* 你的原始数据 */];

// 按日期+名称分组
const groupedData = _.groupBy(data, item => `${item.date}_${item.name}`);

const result = Object.values(groupedData).map(group => {
  const mergedGroup = {
    date: group[0].date,
    name: group[0].name,
    items: []
  };
  
  // 合并所有物品并累加count
  mergedGroup.items = _.flatMap(group, 'items').reduce((acc, item) => {
    const targetItem = _.find(acc, { item_id: item.item_id });
    if (targetItem) {
      targetItem.count += item.count;
    } else {
      acc.push({
        item_id: item.item_id,
        name: item.item.item_name,
        count: item.count
      });
    }
    return acc;
  }, []);
  
  return mergedGroup;
});

console.log(result);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 09:36:27