通用JS数组去重工具函数需支持基础值、对象及嵌套结构,提供keyFn、compare(strict/shallow/custom)、keepLast等配置,不修改原数组,返回新数组,并可链式调用map/filter/resolve。

JS 中实现通用的多功能数组去重工具函数,关键在于支持多种数据类型(基础值、对象、嵌套结构)、可配置去重策略(严格相等、浅比较、深比较、自定义 key 或回调),同时保持简洁、可复用和性能可控。
支持基础类型与引用类型的统一去重
基础类型(string/number/boolean/null/undefined/Symbol)可用 Set 直接去重;但对象、数组等引用类型需额外处理。一个通用方案是提供 keyFn 参数:用户可传入提取唯一标识的函数,例如按对象的 id 字段去重:
-
默认行为:对基础值直接用
Array.from(new Set(arr)) -
对象数组场景:传入
item => item.id,内部根据返回值是否重复决定保留哪个元素(保留首次出现) - 注意稳定性:不修改原数组,返回新数组;重复项只保留第一个匹配的元素
支持浅比较与深比较模式
当无法提供稳定 key(如临时对象、无 id 数据)时,可选比较方式:
-
浅比较(默认关闭):用
JSON.stringify序列化后比对(仅适用于可安全序列化的纯对象/数组,不含函数、undefined、Symbol、循环引用) -
深比较(需谨慎启用):引入轻量逻辑(如递归比对属性值),或依赖成熟工具如
lodash.isEqual;建议作为可选插件式能力,避免主函数体积膨胀 -
推荐做法:默认不开启深比较,通过
compare: 'shallow' | 'deep' | 'custom'配置开关,并允许传入自定义比较函数(a, b) => boolean
支持去重 + 映射 + 过滤的一体化链式调用
真正“多功能”不止于去重,而是能组合常见数组操作。可设计成工厂函数,返回带方法的对象:
-
unique():执行去重(按当前配置) -
map(fn):在去重前/后映射(如先取item.name再去重字符串) -
filter(fn):预过滤,减少后续计算量 -
resolve():最终触发执行并返回结果数组
示例:arrayTools(data).filter(x => x.status === 'active').map(x => x.id).unique().resolve()
兼顾性能与灵活性的参数设计
避免过度抽象,核心参数控制清晰:
-
key?: string | ((item: any) => any):指定字段名或提取函数,优先级最高 -
compare?: 'strict' | 'shallow' | ((a, b) => boolean):严格(===)、浅比(JSON.stringify)、或完全自定义 -
keepLast?: boolean:是否保留最后一次出现的重复项(默认false,保留首次) -
mutate?: boolean:是否允许修改原数组(默认false)
这样既覆盖常见需求,又不会让接口难以理解和测试。


















