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

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])
    }
  }
}
  1. 未初始化数组:this.c[i]在第一次遇到某个ID时是undefined,直接调用push会抛出错误;
  2. 低效的双层循环:遍历整个数组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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 18:07:41