递归处理多维数组去重的核心是先扁平化再用set去重,或遍历中用set记录已见值;推荐递归扁平化+set方案,简洁可靠;需注意nan、null、undefined及对象引用等边界情况。

用递归处理多维数组去重,核心是:先扁平化再去重,或边遍历边收集唯一值。JS 中没有原生的“递归去重”方法,需手动实现深度遍历 + 去重逻辑。
递归扁平化 + Set 去重(推荐)
先用递归把嵌套数组完全展开成一维,再用 Set 去重,简洁可靠,适合大多数场景。
示例代码:
function flattenAndUnique(arr) {
const flat = [];
function dfs(item) {
if (Array.isArray(item)) {
item.forEach(dfs);
} else {
flat.push(item);
}
}
dfs(arr);
return [...new Set(flat)];
}
// 使用
const nested = [1, [2, 3, [2, 4]], 3, [5, [1, 6]]];
console.log(flattenAndUnique(nested)); // [1, 2, 3, 4, 5, 6]
递归过程中边遍历边去重(保留首次出现顺序)
如果需要在深度遍历中跳过已见过的值(尤其对引用类型或自定义相等逻辑有要求),可用一个 Set 记录已出现的原始值,避免重复加入结果。
DMap GL地图JSAPI(dmapgl)开发指南。用于编写、审查、调试 DMap 地图 API 代码,涵盖地图初始化、覆盖物渲染、图层管理、事件处理、控件交互等任务。当用户提及 dmap、dmapgl、jsapi‑gl 或相关地图开发需求时自动触发。
注意:该方式默认只对基础类型(string/number/boolean/null/undefined)安全;若含对象、数组等,需额外实现深比较(不建议在递归中做深比较,性能差且易栈溢出)。
- 用
Set存已见的原始值(仅限可被Set正确识别的类型) - 遇到非数组项,检查是否已存在,不存在才推入结果
- 遇到数组,递归处理子项
function uniqueDeep(arr) {
const seen = new Set();
const result = [];
function dfs(item) {
if (Array.isArray(item)) {
item.forEach(dfs);
} else {
if (!seen.has(item)) {
seen.add(item);
result.push(item);
}
}
}
dfs(arr);
return result;
}
注意事项与边界情况
-
null 和 undefined:
Array.isArray(null)返回false,会被当作普通值处理;如需过滤,可在递归分支中显式判断 -
NaN:
Set能正确去重 NaN(ES6+ 中Set视 NaN 为相同值),但===不行,所以用Set更稳妥 -
对象/数组元素:默认按引用去重;若想按内容去重,应先序列化(如
JSON.stringify),但要注意函数、undefined、Symbol、循环引用会丢失或报错 - 性能:极深嵌套可能触发栈溢出;超大数据建议改用栈模拟递归(迭代 DFS)
扩展:支持自定义比较的递归去重(进阶)
若需按对象字段、忽略大小写字符串等规则去重,可传入比较函数 isEqual,但需注意:每次插入前要遍历已存结果做比较,时间复杂度升为 O(n²),慎用于大数据。
简化示意:
function uniqueDeepBy(arr, isEqual) {
const result = [];
function dfs(item) {
if (Array.isArray(item)) {
item.forEach(dfs);
} else {
const isDup = result.some(x => isEqual(x, item));
if (!isDup) result.push(item);
}
}
dfs(arr);
return result;
}
// 按字符串小写去重
uniqueDeepBy(['A', ['b', 'C']], (a, b) => String(a).toLowerCase() === String(b).toLowerCase());
// → ['A', 'b', 'C']










