JavaScript中嵌套数组按ID分组的实现问题求助
如何按ID对嵌套数组进行分组?
需求回顾
你需要把下面的嵌套数组按子数组第一个元素(ID)进行分组:
const originalArray = [ [ 1, 123412341234, 2.44 ], [ 1, 123912341234, 23.44 ], [ 1, 623412341234, 82.44 ], [ 2, 123412341234, 22.44 ], [ 2, 123412381234, 2.44 ], [ 2, 723412341234, 29.44 ], [ 3, 123412341234, 24.44 ], [ 3, 123412377234, 34.44 ], [ 3, 520312341234, 54.44 ], [ 4, 123412341234, 12.44 ], [ 4, 938412341234, 19.44 ], [ 4, 603412341234, 10.44 ] ];
期望的两种分组形式:
- 形式一:同ID数据被包裹在子数组中,外层是一个大数组
[ [[ 1, 123412341234, 2.44 ], [ 1, 123912341234, 23.44 ], [ 1, 623412341234, 82.44 ]], [[ 2, 123412341234, 22.44 ], [ 2, 123412381234, 2.44 ], [ 2, 723412341234, 29.44 ]], [[ 3, 123412341234, 24.44 ], [ 3, 123412377234, 34.44 ], [ 3, 520312341234, 54.44 ]], [[ 4, 123412341234, 12.44 ], [ 4, 938412341234, 19.44 ], [ 4, 603412341234, 10.44 ]] ] - 形式二:同ID数据作为独立数组分别输出
[[ 1, 123412341234, 2.44 ], [ 1, 123912341234, 23.44 ], [ 1, 623412341234, 82.44 ]] [[ 2, 123412341234, 22.44 ], [ 2, 123412381234, 2.44 ], [ 2, 723412341234, 29.44 ]] [[ 3, 123412341234, 24.44 ], [ 3, 123412377234, 34.44 ], [ 3, 520312341234, 54.44 ]] [[ 4, 123412341234, 12.44 ], [ 4, 938412341234, 19.44 ], [ 4, 603412341234, 10.44 ]]
原代码问题分析
你写的这段代码有两个核心问题:
for(let i = 0; i < this.z.length;i++) { for (let j = 0; j < this.z.length; j++) { if(this.z[j][0]==i){ this.c[i].push(this.z[j]) } } }
- 未初始化数组:
this.c[i]在第一次遇到某个ID时是undefined,直接调用push会抛出错误; - 低效的双层循环:遍历整个数组
this.z.length次,每次又遍历一遍,时间复杂度是O(n²),完全没必要。
解决方案
方法一:用reduce实现(推荐,简洁高效)
Array.prototype.reduce是处理分组类问题的绝佳工具,只需遍历一次数组即可完成分组:
实现形式一
const groupedForm1 = Object.values(originalArray.reduce((acc, item) => { const id = item[0]; // 如果当前ID还没有对应的分组,初始化一个空数组 if (!acc[id]) { acc[id] = []; } // 把当前元素加入对应分组 acc[id].push(item); return acc; }, {})); console.log(groupedForm1); // 输出形式一的结果
实现形式二
形式二本质上就是把形式一的每个分组单独输出,直接遍历形式一的结果即可:
const groupedForm2 = Object.values(originalArray.reduce((acc, item) => { const id = item[0]; if (!acc[id]) { acc[id] = []; } acc[id].push(item); return acc; }, {})); // 逐个输出每个独立的分组数组 groupedForm2.forEach(group => { console.log(group); });
方法二:修复你的for循环代码
如果你更习惯用for循环,只需提前初始化分组数组并记录ID对应的索引即可:
// 假设this.z是你的原始数组 this.c = []; // 用一个对象记录每个ID对应的分组在this.c中的索引 const idToIndex = {}; let currentGroupIndex = 0; for (let i = 0; i < this.z.length; i++) { const currentItem = this.z[i]; const id = currentItem[0]; // 如果当前ID还没被记录,新建一个分组 if (!idToIndex.hasOwnProperty(id)) { this.c[currentGroupIndex] = []; idToIndex[id] = currentGroupIndex; currentGroupIndex++; } // 把当前元素加入对应的分组 this.c[idToIndex[id]].push(currentItem); } console.log(this.c); // 输出形式一的结果 // 如果要输出形式二,遍历this.c逐个打印即可 this.c.forEach(group => console.log(group));
内容的提问来源于stack exchange,提问作者PeopleCallMeLucifer
相关产品推荐
相关产品推荐

