JavaScript多维嵌套数组去重需先标准化结构:基本类型可用JSON.stringify+Set;含对象或深层嵌套需lodash/isEqual深度比对;任意维度可递归标准化后去重;按字段去重则用Map实现O(n)高效过滤。

JavaScript 中处理多维嵌套数组去重,不能直接用 Set 或 indexOf,因为它们只做引用比较或浅层值比较,对嵌套对象/数组无效。关键在于:先让结构可比(序列化或深度比对),再基于该结果过滤重复项。
基本类型组成的多维数组(如二维数值数组)
子数组元素全是数字、字符串等基本类型时,可用 JSON.stringify 转为唯一字符串键:
- 用
map(JSON.stringify)将每个子数组转成字符串 - 套
new Set()去重字符串 - 再用
map(JSON.parse)还原为数组
示例:
const arr = [[1,2], [3,4], [1,2], [5,6]];<br>const unique = Array.from(new Set(arr.map(JSON.stringify))).map(JSON.parse);<br>// → [[1,2], [3,4], [5,6]]
含对象或不规则嵌套的高维数组
当子项是对象、有深层嵌套、或键顺序不固定时,JSON.stringify 会失效(比如 {a:1,b:2} 和 {b:2,a:1} 字符串不同)。这时必须用语义级深度比对:
立即学习“Java免费学习笔记(深入)”;
- 推荐引入
lodash/isEqual,它能正确识别结构等价的对象和数组 - 配合
filter+findIndex实现去重:只保留首次出现且后续无等价项的位置 - 注意性能:
isEqual是 O(n²) 比较,大数据量需评估
示例:
import { isEqual } from 'lodash';<br>const arr = [[{x:1}], [{y:2}], [{x:1}]];<br>const unique = arr.filter((item, i) =><br> i === arr.findIndex(sub => isEqual(sub, item)));<br>// → [[{x:1}], [{y:2}]]
任意维度递归去重(结构扁平化前处理)
如果数组嵌套层级不确定(如 [[1,[2,3]], [4,5], [1,[2,3]]]),可写递归函数统一标准化后再比对:
- 对每个元素判断是否为数组:是则递归调用自身处理
- 递归返回后,用
JSON.stringify或fast-json-stable-stringify(解决键序问题)生成稳定 key - 用
Set记录已见 key,跳过重复
注意:该方式不改变原始嵌套结构,仅按“内容完全一致”去重;若含循环引用、Date、undefined 等非 JSON-safe 类型,需额外预处理或换用深度比对库。
按特定字段去重(对象数组常用)
实际中更多是“数组里每个元素是对象,想按某个字段(如 id)去重”,这不是纯嵌套问题,但常被混淆:
- 用
Map存储已见的字段值,边遍历边过滤 - 比
findIndex+ 全量比对快得多,时间复杂度 O(n) - 适合接口返回的列表数据,字段唯一性明确
示例:
const users = [{id:1,name:'A'}, {id:2,name:'B'}, {id:1,name:'C'}];<br>const seen = new Map();<br>const uniqueByField = users.filter(item => {<br> if (seen.has(item.id)) return false;<br> seen.set(item.id, true);<br> return true;<br>});<br>// → [{id:1,name:'A'}, {id:2,name:'B'}]


















