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

JavaScript按userId合并订单并累加同bookId的count值

解决订单数据按用户分组并累加书籍数量的问题

你需要将orders数组按userId分组去重,同一用户下相同bookId的count值累加,最终生成包含用户基础信息和对应书籍统计的报表。先说说你现有代码的问题:

  • 用[...new Set(orders)]无法实现对象去重,因为对象是引用类型,Set只会对比内存地址,不会识别内容相同的对象,所以uniqueOrder还是原数组的全部元素。
  • 后续的map+filter逻辑只是给每个订单关联了同用户的所有订单,既没实现用户分组,也没完成书籍数量的累加,最终结果会有大量重复的用户条目。

下面是两种可行的实现方案:

方案一:使用Map构建映射(更安全,支持非数字userId)

const orders = [
    {"userId": 1,"name": "Person 1","status": "active","bookId": 24,"count": 1},
    {"userId": 1,"name": "Person 1","status": "active","bookId": 25,"count": 2},
    {"userId": 2,"name": "Person 2","status": "active","bookId": 8,"count": 2},
    {"userId": 1,"name": "Person 1","status": "active","bookId": 24,"count": 3},
    {"userId": 3,"name": "Person 3","status": "active","bookId": 99,"count": 1}
];

// 用reduce遍历订单,构建用户分组的Map
const userMap = orders.reduce((map, order) => {
    if (!map.has(order.userId)) {
        // 初始化用户条目,包含基础信息和存储书籍的Map
        map.set(order.userId, {
            userId: order.userId,
            name: order.name,
            status: order.status,
            orders: new Map()
        });
    }

    const userEntry = map.get(order.userId);
    if (!userEntry.orders.has(order.bookId)) {
        // 初始化书籍统计条目
        userEntry.orders.set(order.bookId, { bookId: order.bookId, count: 0 });
    }

    // 累加书籍数量
    userEntry.orders.get(order.bookId).count += order.count;
    return map;
}, new Map());

// 将Map转换为最终需要的数组格式
const results = Array.from(userMap.values()).map(user => ({
    ...user,
    orders: Array.from(user.orders.values())
}));

console.log(results);

方案二:使用普通对象构建映射(更简洁,适合数字userId)

const orders = [
    {"userId": 1,"name": "Person 1","status": "active","bookId": 24,"count": 1},
    {"userId": 1,"name": "Person 1","status": "active","bookId": 25,"count": 2},
    {"userId": 2,"name": "Person 2","status": "active","bookId": 8,"count": 2},
    {"userId": 1,"name": "Person 1","status": "active","bookId": 24,"count": 3},
    {"userId": 3,"name": "Person 3","status": "active","bookId": 99,"count": 1}
];

const userObj = {};

orders.forEach(order => {
    const { userId, name, status, bookId, count } = order;
    // 初始化用户条目
    if (!userObj[userId]) {
        userObj[userId] = { userId, name, status, orders: {} };
    }

    const user = userObj[userId];
    // 初始化书籍统计条目
    if (!user.orders[bookId]) {
        user.orders[bookId] = { bookId, count: 0 };
    }
    // 累加数量
    user.orders[bookId].count += count;
});

// 将对象转换为最终数组格式
const results = Object.values(userObj).map(user => ({
    ...user,
    orders: Object.values(user.orders)
}));

console.log(results);

两种方案的核心逻辑一致:先按userId完成用户分组,再在每个用户组内按bookId完成数量累加,最后将映射结构转换为你需要的数组格式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 20:48:45