纯JS实现基于键值遍历数组并动态转换数组结构
纯JavaScript动态转换数组方案
当然有办法啦!纯JavaScript就能轻松实现这种动态转换,不管每个section下的元素数量多少都能完美处理。我给你两种常用的高效方案,你可以根据自己的代码风格和需求选择:
方案一:使用Array.reduce()(推荐)
reduce是处理数组分组聚合的利器,我们可以用它遍历原数组,将同section的元素数值聚合到一起,最后再转换为目标数组结构。
// 假设你的原数组结构是这样的(可根据实际情况调整属性名) const array1 = [ { section: "Math", score: 85 }, { section: "Math", score: 92 }, { section: "English", score: 78 }, { section: "Science", score: 90 }, { section: "Science", score: 88 }, { section: "Science", score: 95 } ]; // 动态转换为目标数组array2 const array2 = Object.values(array1.reduce((acc, curr) => { // 如果当前section未在累加器中,初始化一个新的分组对象 if (!acc[curr.section]) { acc[curr.section] = { section: curr.section, values: [] }; } // 将当前元素的数值推入对应分组的values数组 acc[curr.section].values.push(curr.score); return acc; }, {})); console.log(array2); // 输出结果: // [ // { section: "Math", values: [85, 92] }, // { section: "English", values: [78] }, // { section: "Science", values: [90, 88, 95] } // ]
代码说明:
reduce的第一个参数是回调函数,acc是临时存储分组的累加器(初始值为{}),curr是当前遍历到的数组元素。- 每次遍历会检查当前
section是否已存在于acc中,不存在则创建包含section名称和空values数组的对象。 - 把当前元素的数值(这里是
score,你可以换成自己的属性名,比如value)推入对应分组的values数组。 - 最后用
Object.values()把累加器对象转换为数组,就得到了我们需要的array2。
方案二:使用Map结构
如果你更习惯用Map来处理键值对,这种方案也很直观:
const array1 = [ { section: "Math", score: 85 }, { section: "Math", score: 92 }, { section: "English", score: 78 }, { section: "Science", score: 90 }, { section: "Science", score: 88 }, { section: "Science", score: 95 } ]; const sectionMap = new Map(); // 遍历原数组填充Map array1.forEach(item => { if (!sectionMap.has(item.section)) { sectionMap.set(item.section, { section: item.section, values: [] }); } sectionMap.get(item.section).values.push(item.score); }); // 将Map的值转换为数组得到array2 const array2 = Array.from(sectionMap.values());
代码说明:
Map的键是section名称,值是对应的分组对象。- 遍历原数组时,检查
Map中是否存在当前section,不存在则添加新条目,然后将数值推入values数组。 - 最后用
Array.from()把Map的所有值转换为数组,得到目标结构。
适配不同属性名与数学运算
这两种方案都是完全动态的:
- 如果你的原数组中存储数值的属性不是
score,而是value或者其他名称,只需要把代码中的curr.score换成curr.你的属性名即可。 - 转换后的
array2可以直接用于数学运算,比如计算每个section的平均分、总分:
// 计算每个section的平均分和总分 const resultWithStats = array2.map(group => ({ ...group, total: group.values.reduce((sum, val) => sum + val, 0), average: group.values.reduce((sum, val) => sum + val, 0) / group.values.length })); console.log(resultWithStats); // 输出结果: // [ // { section: "Math", values: [85,92], total: 177, average: 88.5 }, // { section: "English", values: [78], total:78, average:78 }, // { section: "Science", values: [90,88,95], total:273, average:91 } // ]
内容的提问来源于stack exchange,提问作者Tony Hensler
相关产品推荐
相关产品推荐

