如何使用reduce过滤对象数组,提取指定语言的对应城市计数?
代码问题分析与正确实现
你的代码存在的问题
- 未按目标语言过滤:
languages是数组,直接访问languages.details完全错误——数组本身没有details属性,必须先从languages数组中筛选出指定名称的语言对象。 - 未针对城市匹配count值:就算拿到目标语言的
details(同样是数组),直接取details.count也不成立,需要遍历details数组找到对应城市的条目才能获取count。 - 缺失默认值处理逻辑:
|| 0的写法完全没起到“找不到城市填0”的作用,因为前面的属性访问本身就是undefined,逻辑路径错误。
正确实现方案
封装一个函数,接收输入数组和目标语言参数,通过reduce完成遍历与数据提取:
function getLanguageCityCounts(input, targetLanguage) { return input.reduce((result, item) => { // 找到当前对象中匹配目标语言的条目 const langItem = item.languages.find(lang => lang.name === targetLanguage); // 提取该语言的details,无匹配时用空数组兜底 const details = langItem ? langItem.details : []; // 查找japan的count,无匹配则填0 const japanCount = details.find(d => d.city === 'japan')?.count || 0; // 查找usa的count,无匹配则填0 const usaCount = details.find(d => d.city === 'usa')?.count || 0; result.japan.push(japanCount); result.usa.push(usaCount); return result; }, { japan: [], usa: [] }); }
使用示例
const input = [ { "metadata": { "id": 1071, "name": "First" }, "languages": [ { "name": "Alpha", "details": [ { "city": "usa", "count": 33 } ] }, { "name": "Beta", "details": [ { "city": "japan", "count": 3 } ] }, ] }, { "metadata": { "id": 1068, "name": "Second" }, "languages": [ { "name": "Alpha", "details": [ { "city": "japan", "count": 10 }, { "city": "usa", "count": 20 } ] }, { "name": "Beta", "details": [ { "city": "japan", "count": 15 }, { "city": "usa", "count": 25 } ] }, ] }, ]; // 过滤Alpha的情况 console.log(getLanguageCityCounts(input, 'Alpha')); // 输出: { japan: [0, 10], usa: [33, 20] } // 过滤Beta的情况 console.log(getLanguageCityCounts(input, 'Beta')); // 输出: { japan: [3, 15], usa: [0, 25] }
代码说明
- 语言筛选:用
Array.find精准定位目标语言的对象,确保后续操作的是正确的数据集合。 - 城市count提取:用
Array.find匹配对应城市,通过可选链?.避免找不到条目时抛出错误,配合|| 0实现“无匹配填0”的需求。 - 结果聚合:将每个对象的城市count依次推入结果数组,最终生成符合要求的结构。
内容的提问来源于stack exchange,提问作者Aren Trot
相关产品推荐
相关产品推荐

