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

将含重复元素的数组拆分为唯一元素数组与重复元素组数组

更优的数组拆分方案:一次遍历完成分类

嘿,我来分享一个更高效的解决方案——只用单次遍历就能完成你需要的数组拆分,相比你之前的reduce方案,它省去了中间分组数组的创建,也不需要后续的过滤和映射操作,性能和可读性都更出色:

const array = [1,2,2,3,4,4,4,5,6,7,7,7,8,9];
const uniqArray = [];
const dupArray = [];

// 处理空数组的边界情况
if (array.length === 0) {
  console.log(uniqArray, dupArray);
  return;
}

// 初始化当前分组,从第一个元素开始
let currentGroup = [array[0]];

for (let i = 1; i < array.length; i++) {
  const currentItem = array[i];
  // 如果当前元素和分组首元素相同,加入当前分组
  if (currentItem === currentGroup[0]) {
    currentGroup.push(currentItem);
  } else {
    // 当前分组结束,判断是唯一元素还是重复组
    if (currentGroup.length === 1) {
      uniqArray.push(currentGroup[0]);
    } else {
      dupArray.push(currentGroup);
    }
    // 开启新的分组
    currentGroup = [currentItem];
  }
}

// 别忘了处理最后一个分组!
if (currentGroup.length === 1) {
  uniqArray.push(currentGroup[0]);
} else {
  dupArray.push(currentGroup);
}

console.log(uniqArray); // 输出: [1,3,5,6,8,9]
console.log(dupArray); // 输出: [[2,2],[4,4,4],[7,7,7]]

为什么这个方案更好?

  • 时间效率拉满:整个过程只遍历数组一次,时间复杂度是O(n),是理论上的最优复杂度。你之前的reduce方案虽然也是线性时间,但后续的两次filter+map会额外增加少量开销。
  • 内存更节省:没有创建像arrayOfArrays这样的中间分组数组,只用了一个临时变量currentGroup来跟踪当前组,内存占用更低。
  • 逻辑清晰易懂:每一步都直接处理分组和分类,没有绕弯,后续维护起来也很方便。

顺便聊聊你之前的尝试

你第一次用forEach的方案,问题出在判断条件item !== array[index + 1]上——这个条件会把重复元素的最后一个前的元素都放进临时数组,但最后一个重复元素会被误判为唯一元素塞进uniqArray,导致结果出错。而这个一次遍历的方案通过跟踪完整分组,完美避免了这个问题。

你的reduce方案其实思路是对的,但多了中间分组的步骤,显得有点冗余,上面的方案把分组和分类合并到了一次遍历里,更加紧凑。

内容的提问来源于stack exchange,提问作者Rami

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 15:47:39