如何将对象数组转换为指定结构对象?代码问题排查
数组转按年份分组对象的实现与问题排查
需求概述
给定如下对象数组:
const arr = [ {year: 2023, language: 'react'}, {year: 2023, language: 'node'}, {year: 2022, language: 'mongodb'}, {year: 2022, language: 'javascript'}, {year: 2021, language: 'jquery'}, ]
需要转换为按年份作为键、对应语言数组作为值的目标结构:
const obj = { '2023': ['react', 'node'], '2022': ['mongodb', 'javascript'], '2021': ['jquery'] }
实现方案
方法1:使用Array.reduce()(推荐)
reduce是处理数组分组场景的高效方法,通过累加器逐步构建目标对象:
const arr = [ {year: 2023, language: 'react'}, {year: 2023, language: 'node'}, {year: 2022, language: 'mongodb'}, {year: 2022, language: 'javascript'}, {year: 2021, language: 'jquery'}, ]; const groupedObj = arr.reduce((acc, item) => { // 将年份转为字符串,保证键类型统一 const yearKey = String(item.year); // 若当前年份键不存在,初始化空数组 if (!acc[yearKey]) { acc[yearKey] = []; } // 推入对应语言值 acc[yearKey].push(item.language); return acc; }, {}); console.log(groupedObj); // 输出:{ '2021': [ 'jquery' ], '2022': [ 'mongodb', 'javascript' ], '2023': [ 'react', 'node' ] }
方法2:使用Array.forEach()
如果对reduce不熟悉,forEach是更直观的遍历实现方式:
const groupedObj = {}; arr.forEach(item => { const yearKey = String(item.year); if (!groupedObj[yearKey]) { groupedObj[yearKey] = []; } groupedObj[yearKey].push(item.language); });
常见转换问题排查
- 年份键类型不统一:若原数组中
year存在数字和字符串混合的情况(如2023和'2023'),会生成两个独立的键。解决方式是统一将year转为字符串或数字后作为键。 - 未初始化数组导致报错:直接执行
acc[yearKey].push(...)而不先判断数组是否存在,首次处理某年份时会抛出Cannot read properties of undefined (reading 'push')错误。必须先初始化空数组。 - 重复语言值未去重:若原数组同一年份下存在重复的
language值,默认会重复推入数组。如需去重,可在push前判断:if (!acc[yearKey].includes(item.language)) acc[yearKey].push(item.language)。 - 无效数据未过滤:若数组中存在缺少
year或language属性的元素,会导致键为undefined或数组中出现undefined。可提前过滤无效数据:const validArr = arr.filter(item => item.year && item.language);。 - 意外修改原数组:如果在处理过程中修改了
item的属性(如item.language = 'xxx'),会直接改变原数组元素。确保只读取属性值,不修改原数组元素。
内容的提问来源于stack exchange,提问作者Siddharth Chauhan
相关产品推荐
相关产品推荐

