uniqBy
时间: 2025-08-16 10:05:08 浏览: 9
<think>嗯,用户想了解如何使用或实现Lodash的uniqBy函数。首先,我得回忆一下uniqBy的功能。根据引用[2],uniqBy的作用是对数组进行去重,可以指定一个迭代函数或属性名,根据处理后的值来判断是否重复。比如,数组对象根据某个属性去重,或者数值数组根据Math.floor后的结果去重。
用户可能已经看过文档,但需要具体的例子或实现方式。我需要先解释用法,再给出实现思路。引用中的例子显示,使用uniqBy时,第二个参数可以是函数或字符串(属性名)。比如,用Math.floor处理数值数组,或者用'x'属性对对象数组去重。
接下来,用户可能想知道如何自己实现这样的函数。这时候需要考虑几种情况:参数是函数还是字符串,如何处理不同的数据类型。对于字符串参数,可以将其转换为访问对象属性的函数。然后,遍历数组,用迭代函数处理每个元素,记录已经出现过的值,保留第一次出现的元素。
代码实现方面,可以用一个对象或Set来存储已处理的键。对于每个元素,用迭代函数获取键,如果键不存在,则保留该元素,并将键加入已存在的集合中。需要注意的是,对象的情况可能需要处理键的序列化,比如使用JSON.stringify,但引用中的例子似乎直接比较原始值,所以可能不需要复杂处理。
另外,用户可能关心性能,比如使用哈希表的时间复杂度是O(n),但如果有大量数据,可能需要优化。同时,对于对象的处理,是否要深比较?引用中的例子用的是浅比较,比如根据属性'x'去重,而深比较可能需要使用像_.isEqual这样的方法,但uniqBy本身可能不处理这种情况,uniqWith才用自定义比较。
在实现的时候,还要考虑边缘情况,比如元素是null或undefined时的处理,以及迭代函数返回的值类型是否适合作为键(比如对象不能作为对象的键,需要转成字符串)。
最后,总结用法和实现步骤,确保用户能理解并应用。可能还需要比较Lodash的实现和自己实现的差异,指出需要注意的地方。</think>### 如何实现和使用 `uniqBy` 函数?
#### 一、`uniqBy` 的核心作用
`uniqBy` 用于对数组进行去重操作,**根据迭代函数或属性名**提取特征值,保留首次出现的元素。例如:
- 对数值数组按 `Math.floor` 去重:$[2.1, 1.2, 2.3]$ → 去重后为 $[2.1, 1.2]$(因 $2.1$ 和 $2.3$ 的 `floor` 值均为 $2$)[^2]
- 对对象数组按属性 `x` 去重:$[\{x:1\},\{x:1\},\{x:2\}]$ → 结果为 $[\{x:1\},\{x:2\}]$[^1]
#### 二、使用方法(Lodash)
1. **安装与引入**:
```bash
npm install lodash
```
```typescript
import uniqBy from 'lodash/uniqBy';
```
2. **基础语法**:
```javascript
_.uniqBy(array, [iteratee=_.identity])
```
3. **示例**:
```javascript
// 对象数组按属性去重
const arr = [{x:1}, {x:1}, {x:2}];
const result = _.uniqBy(arr, 'x'); // 输出: [{x:1}, {x:2}]
// 数值数组按函数处理去重
const nums = [2.1, 1.2, 2.3];
const filtered = _.uniqBy(nums, Math.floor); // 输出: [2.1, 1.2]
```
#### 三、手动实现 `uniqBy`
若需自行实现类似功能,步骤如下:
1. **参数处理**:
根据第二个参数是函数还是字符串,生成对应的迭代函数。
例如,`'x'` → `(item) => item.x`
2. **遍历与去重逻辑**:
使用 `Set` 或对象存储已出现的特征值,保留首次出现的元素。
```javascript
function uniqBy(arr, iteratee) {
const seen = new Set();
const getKey = typeof iteratee === 'function'
? iteratee
: (item) => item[iteratee];
return arr.filter(item => {
const key = getKey(item);
if (!seen.has(key)) {
seen.add(key);
return true;
}
return false;
});
}
```
**测试用例**:
```javascript
const arr = [{x:1}, {x:1}, {x:2}];
console.log(uniqBy(arr, 'x')); // 输出: [{x:1}, {x:2}]
```
#### 四、性能与注意事项
1. **时间复杂度**:$O(n)$,依赖哈希表的高效查找
2. **特殊值处理**:
- `NaN` 需特殊判断(`Set` 默认认为 `NaN !== NaN`,需单独处理)
- 对象属性值为 `undefined` 时可能被误判
#### 五、与其他去重方法对比
| 方法 | 适用场景 | 复杂度 |
|------------------|--------------------------|--------|
| `Array.from(new Set(arr))` | 基础值类型去重 | $O(n)$ |
| `uniqBy` | 对象数组或自定义特征值去重 | $O(n)$ |
| `uniqWith` | 深度比较对象是否相等 | $O(n^2)$[^3] |
阅读全文
相关推荐














