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

如何在JavaScript中删除二维数组中的重复子数组?

删除二维数组中重复子数组的解决方案

需求说明

需要从ground二维数组中删除所有与deleteBlock内子数组内容完全重复的项。

原始数据

let ground = [
  [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
  [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
  [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
  [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
  [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
  [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
  [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
  [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
  [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
  [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
  [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
  [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
  [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
  [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
  [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
  [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
  [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
  [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
  [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
  [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
  [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
  [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
  [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
  [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
  [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
  [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
  [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
  [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
  [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
  [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
  [1,3,3,7,7,7,7,8,8,4,4,4,2,2,3,7,1],
  [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
]

let deleteBlock = [[1,3,3,7,7,7,7,8,8,4,4,4,2,2,3,7,1]]

你尝试方法的问题分析

第一种方法

let ans = ground.filter((r,idx) => {
    for(let i =0; i < deleteBlock.length;i++) {
     if(r === deleteBlock[i]) {
        ground.splice(idx, 1)
     }
    }
})
  • 引用类型比较错误:数组是引用类型,===比较的是内存地址而非内容,所以r === deleteBlock[i]永远为false,不会触发splice。
  • filter使用错误:filter的回调需要返回布尔值决定是否保留元素,此代码没有返回值,且在filter中直接用splice修改原数组会打乱遍历顺序,导致结果异常。

第二种方法

ground.filter((r) => deleteBlock.forEach(ele=> r.includes(ele)))
  • forEach无返回值:forEach不会返回任何值,所以filter的回调始终得到undefined(视为假值),最终会过滤掉所有元素。
  • includes误用:r.includes(ele)是判断数组r是否包含ele这个整体(即子数组是否是r的元素),而非判断两个数组内容是否相等。

正确解决方案

方法一:逐个元素比较(直观易懂)

先写一个辅助函数判断两个数组内容是否完全相等,再用filter结合some过滤:

// 辅助函数:判断两个数组内容是否完全一致
function arraysEqual(arr1, arr2) {
  if (arr1.length !== arr2.length) return false;
  for (let i = 0; i < arr1.length; i++) {
    if (arr1[i] !== arr2[i]) return false;
  }
  return true;
}

// 过滤ground数组
const filteredGround = ground.filter(subArr => {
  // 只要deleteBlock中有一个子数组和当前subArr相等,就过滤掉它
  return !deleteBlock.some(block => arraysEqual(subArr, block));
});

方法二:转字符串存Set(性能更优)

把deleteBlock中的子数组转成JSON字符串存入Set,利用Set的O(1)查找效率快速判断,适合处理大数据量:

// 将deleteBlock的子数组转为字符串存入Set
const deleteStringSet = new Set(deleteBlock.map(block => JSON.stringify(block)));

// 过滤ground:当前子数组转字符串后不在Set中则保留
const filteredGround = ground.filter(subArr => {
  return !deleteStringSet.has(JSON.stringify(subArr));
});

验证结果

两种方法都会得到去掉了目标子数组的filteredGround,原ground中倒数第二个子数组会被正确删除。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 23:39:20