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

JavaScript中使用reduce统计对象数组的用户操作次数问题

问题:使用reduce统计用户各类操作次数失败

首先我有一组社交操作数据:

const tweets = [
  {'action': 'tweet', 'user': 'loser', 'message': 'fooboo'},
  {'action': 'follow', 'user': 'loser', 'message': null },
  {'action': 'tweet', 'user': 'loser', 'message': 'hello'},
  {'action': 'retweet', 'user': 'loser', 'message': null},
  {'action': 'tweet', 'user': 'michael', 'message': 'CIA is watching'},
  {'action': 'tweet', 'user': 'michael', 'message': 'HEHEHEHE'},
  {'action': 'follow', 'user': 'michael', 'message': null }
];

我想用reduce方法遍历数组,统计每个用户的各类操作次数,期望输出是:

{
  loser: { tweets: 2, retweets: 1, follows: 1 },
  michael: { tweets: 2, retweets: 0, follows: 1 }
}

但我写的代码无法得到正确结果:

let userCount = tweets.reduce(function(users, line, idx) {
  users[line['users']] = users[line['user']] || [];
  let action = line['action'];
  users[line.user].push({ action: users[line.user].action + 1 || 0 })
  return users
}, {users: []});

当前错误输出是:

{
  michael: [ { action: 1 } ],
  loser: [ { action: 1 }, { action: 1 }, { action: 1 } ],
}

解决方案

咱们一步步来修正你的代码:

1. 修正核心错误点

你的代码里有几个关键问题:

  • 拼写错误:line['users']多了个s,应该是line['user']或者line.user
  • 初始值错误:初始给的{users: []}不符合需求,应该用空对象{},方便以用户名作为键存储统计数据
  • 用户结构错误:你给每个用户初始化了数组,但我们需要的是包含tweets/retweets/follows的对象
  • 计数逻辑错误:用push添加对象的方式完全不对,应该直接对对应操作的数值进行累加

2. 正确实现代码

这里提供两种写法,你可以根据习惯选择:

写法一:用switch分支处理操作类型

const tweets = [
  {'action': 'tweet', 'user': 'loser', 'message': 'fooboo'},
  {'action': 'follow', 'user': 'loser', 'message': null },
  {'action': 'tweet', 'user': 'loser', 'message': 'hello'},
  {'action': 'retweet', 'user': 'loser', 'message': null},
  {'action': 'tweet', 'user': 'michael', 'message': 'CIA is watching'},
  {'action': 'tweet', 'user': 'michael', 'message': 'HEHEHEHE'},
  {'action': 'follow', 'user': 'michael', 'message': null }
];

const userCount = tweets.reduce((users, line) => {
  // 初始化用户统计结构:如果用户不存在,就创建一个默认计数全为0的对象
  users[line.user] = users[line.user] || { tweets: 0, retweets: 0, follows: 0 };
  
  // 根据操作类型对应累加计数
  switch(line.action) {
    case 'tweet':
      users[line.user].tweets++;
      break;
    case 'retweet':
      users[line.user].retweets++;
      break;
    case 'follow':
      users[line.user].follows++;
      break;
    // 可选:处理未知操作类型
    default:
      console.warn(`未知操作类型:${line.action}`);
      break;
  }
  
  return users;
}, {}); // 初始值设为空对象

console.log(userCount);

写法二:用操作映射简化代码(更简洁)

const tweets = [
  {'action': 'tweet', 'user': 'loser', 'message': 'fooboo'},
  {'action': 'follow', 'user': 'loser', 'message': null },
  {'action': 'tweet', 'user': 'loser', 'message': 'hello'},
  {'action': 'retweet', 'user': 'loser', 'message': null},
  {'action': 'tweet', 'user': 'michael', 'message': 'CIA is watching'},
  {'action': 'tweet', 'user': 'michael', 'message': 'HEHEHEHE'},
  {'action': 'follow', 'user': 'michael', 'message': null }
];

// 建立操作名和统计键名的映射关系
const actionToKey = {
  tweet: 'tweets',
  retweet: 'retweets',
  follow: 'follows'
};

const userCount = tweets.reduce((users, line) => {
  users[line.user] = users[line.user] || { tweets: 0, retweets: 0, follows: 0 };
  // 找到对应的统计键名,然后累加
  const targetKey = actionToKey[line.action];
  if (targetKey) {
    users[line.user][targetKey]++;
  }
  return users;
}, {});

console.log(userCount);

运行任意一种写法,都能得到你期望的统计结果啦。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:21:31