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

JavaScript如何统计对象数组中属性值的出现次数

问题说明

你给出的示例数组存在语法笔误:第一个国家对象缺少闭合的},修正后的基础测试数据如下:

const countriesSample = [{
    name: "Yemen",
    capital: "Sana'a",
    languages: ["Arabic"],
  },
  {
    name: "Zambia",
    capital: "Lusaka",
    languages: ["English"],
  },
  {
    name: "Zimbabwe",
    capital: "Harare",
    languages: ["Shona", "English", "Northern Ndebele"],
  },
];

需求是统计所有国家languages数组中每个语言的出现次数,最终输出{language: 语言名, count: 出现次数}格式的数组,且不使用显式for循环实现。

你之前写的循环逻辑存在几个明显错误:

  • 内层循环遍历countries[i].length没有意义,countries[i]是单个国家对象,不存在length属性,应该遍历的是countries[i].languages
  • 计数逻辑错误,你在累加数组长度,没有按单个语言维度分类统计,只能得到所有语言的总数量,得不到每个语言的单独计数
  • 索引使用混乱,内层循环用j索引取countries[j]属于逻辑错位
实现方案

直接用数组内置方法组合即可实现,不需要写显式for循环。

基础实现(和示例输出顺序一致)

核心逻辑分三步:先把所有嵌套的语言数组拍平成一维列表,再统计每个语言的出现频次,最后转换成要求的结构并按频次降序排序:

// 1. 拍平+统计频次
const langCount = countriesSample
  .flatMap(country => country.languages)
  .reduce((res, lang) => {
    res[lang] = (res[lang] || 0) + 1;
    return res;
  }, {});

// 2. 格式转换+排序
const result = Object.entries(langCount)
  .map(([language, count]) => ({language, count}))
  .sort((a, b) => b.count - a.count);

运行后得到的结果和你给出的期望输出完全一致。

逻辑说明

  • flatMap会遍历每个国家项,取出languages数组后自动把所有数组合并成一维的语言列表,比先map再flat的写法性能更好
  • reduce用一个普通对象做哈希表,遍历一维语言列表时累计每个语言的出现次数
  • Object.entries把存统计结果的对象转成[语言名, 计数]格式的二维数组,再通过map转成要求的对象结构
  • 最后加的sort是为了让出现次数高的语言排在前面,和你给出的示例顺序匹配

更稳妥的实现(避免键名冲突)

如果担心语言名和Object原型上的属性重名导致统计异常,可以用Map作为统计容器:

const langCountMap = countriesSample
  .flatMap(country => country.languages)
  .reduce((map, lang) => {
    map.set(lang, (map.get(lang) || 0) + 1);
    return map;
  }, new Map());

const result = Array.from(langCountMap, ([language, count]) => ({language, count}))
  .sort((a, b) => b.count - a.count);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 07:36:18