使用 filter 和 Map 根据键值去重
我来详细解释方法2,这是一种高效且简洁的数组去重方法,特别适合根据对象中的某个键值进行去重操作。
完整代码
function uniqueByKey(arr, key) {return [...new Map(arr.map(item => [item[key], item])).values()];
}分步解析
让我们分解这个方法的每个步骤:
arr.map(item => [item[key], item])遍历原始数组,为每个元素创建一个新数组
新数组的第一个元素是对象的键值(
item[key])第二个元素是对象本身(
item)例如,对于
{id: 1, name: 'John'},当 key 是 'id' 时,会变成[1, {id: 1, name: 'John'}]
new Map()将上一步生成的数组对传递给
Map构造函数Map对象会自动处理键值对,当有相同的键时,后面的值会覆盖前面的值这是去重的关键步骤,因为
Map的键必须是唯一的
.values()获取
Map中所有的值(即原始对象)这会返回一个
MapIterator对象
[... ]使用扩展运算符将
MapIterator转换为普通数组
为什么这个方法有效?
Map对象的特点是键必须是唯一的当我们把对象的键值作为
Map的键,对象本身作为值时:如果遇到相同的键值,后面的对象会覆盖前面的对象
最终
Map中只保留每个键值的最后一个对象
通过
values()方法,我们只获取对象部分,忽略键
示例演示
假设我们有如下数组:
const data = [{id: 1, name: 'John'},{id: 2, name: 'Jane'},{id: 1, name: 'Johnny'}, // 重复的 id:1{id: 3, name: 'Alice'}
];执行步骤:
data.map(item => [item['id'], item])生成:[[1, {id: 1, name: 'John'}],[2, {id: 2, name: 'Jane'}],[1, {id: 1, name: 'Johnny'}],[3, {id: 3, name: 'Alice'}] ]new Map()处理后:Map {1 => {id: 1, name: 'Johnny'}, // 后面的覆盖了前面的2 => {id: 2, name: 'Jane'},3 => {id: 3, name: 'Alice'} }.values()获取:MapIterator {{id: 1, name: 'Johnny'},{id: 2, name: 'Jane'},{id: 3, name: 'Alice'} }[... ]转换为数组:[{id: 1, name: 'Johnny'},{id: 2, name: 'Jane'},{id: 3, name: 'Alice'} ]
注意事项
保留最后一个重复项:这个方法会保留最后一个遇到的重复键值对象,而不是第一个
性能优势:对于大型数组,这种方法通常比其他方法(如使用
filter+find)性能更好,因为Map的查找操作是 O(1) 复杂度键值类型:键值可以是任何类型,但会被
Map转换为字符串形式进行比较
如果需要保留第一个遇到的重复项而不是最后一个,可以先将数组反转,处理后再反转回来:
function uniqueByKeyKeepFirst(arr, key) {return [...new Map([...arr].reverse().map(item => [item[key], item])).values()].reverse();
}![[特殊字符] Python 批量生成词云:读取词频 Excel + 自定义背景 + Excel to.png 流程解析](http://pic.xiahunao.cn/[特殊字符] Python 批量生成词云:读取词频 Excel + 自定义背景 + Excel to.png 流程解析)