可手写支持链式调用的数组去重工具,通过包装器对象缓存原数组、提供.uniq()(支持默认/字段名/函数三种去重策略)和.value()方法,内部用set实现o(1)查重,返回新包装器保持链式。

可以用类似 lodash 的链式风格手写数组去重,核心是返回一个可继续调用的对象,内部维护原始数据,并在最终调用 .value() 时执行去重逻辑。
基础链式结构设计
创建一个包装器函数,接收数组后返回带方法的对象:
- 构造时缓存原始数组(避免多次操作污染原数据)
- 提供
.uniq()方法返回新包装器(支持链式) - 提供
.value()方法触发实际去重并返回结果
支持多种去重策略(类似 lodash 的 iteratee)
让 .uniq() 支持传入回调函数或键名字符串,适配不同场景:
-
.uniq():默认按===去重(基础类型) -
.uniq('id'):按对象某个字段去重 -
.uniq(item => item.name.toLowerCase()):自定义提取值逻辑
内部用 Map 或 Set 缓存已见的 key,保证 O(1) 查重效率。
详细的 Three.js 3D 图形参考,涵盖场景设置、相机、几何体、材质、光照、动画、控制器、加载器、数学工具和调试。
兼容原生数组方法(可选增强)
让包装器对象“假装”是数组(鸭子类型),支持 .map、.filter 等直接调用(不改变链式语义):
- 重写
Symbol.iterator让for...of和展开运算符可用 - 代理常用数组方法,返回新包装器而非原生数组(保持链式)
- 例如:
_(arr).map(x => x * 2).uniq().value()
简单实现示例
以下是最简可用版本(无代理、无 Symbol,仅核心链式 + 多种去重):
function _(arr) {
const value = Array.isArray(arr) ? arr.slice() : [];
<p>return {
uniq: function (iteratee) {
const seen = new Set();
const result = [];</p><pre class="brush:php;toolbar:false;"> for (const item of value) {
let key;
if (typeof iteratee === 'string') {
key = item[iteratee];
} else if (typeof iteratee === 'function') {
key = iteratee(item);
} else {
key = item;
}
if (!seen.has(key)) {
seen.add(key);
result.push(item);
}
}
return _(result); // 返回新包装器,支持链式
},
value: function () {
return result || value;
}}; }
用法:_(data).uniq('id').value() 或 _(nums).uniq().value()。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










