概要
这是一篇记录文,记录数组操作对象去重的实现。
需求
有这样一个数组
[{ _id: 123, name: '张三' },{ _id: 124, name: '李四' },{ _id: 123, name: '张三' }]
实际上我们只需要
[{ _id: 123, name: '张三' },{ _id: 124, name: '李四' }]
去重
简单数组的去重
Array.from(new Set([1,1,2,3,4,4])) // [1,2,3,4]
以对象为元素的数组去重
和数组相关的算法多种多样,在你以为自己已经掌握数组之后,会发现很多和数组相关的算法仍旧很复杂。
下面我将讲述一个入门等级的数组算法,解决上面提出的需求。
1、定义一个函数removeRepeat,它需要传入2个参数,arr表示需要去重的数组,field表示需要比较的key。比如我们的需求是比较 _id 是否有重复。
function removeRepeat(arr, field){ return arr }
2、需要一个空数组,用来存储每个对象元素中field对应的value。
let s = [] for(let v of arr){ s.push(v[field]) } //s = [123, 124, 123]
3、将所有field的值存到数组之后,它们的下标一一对应原数组的下标(这点很重要),接着我们需要2个对象集合,result用来存储s里遍历出来的元素,如果有重复,就将重复的元素丢到reSet对象里面。
let result = {}, reSet = {} for(let i=0,len=s.length;i<len;i++){ if(!result[s[i]] && result[s[i]] !== 0) { //如果result不存在当前的key并且它不为0时 result[s[i]] = i } else { reSet[s[i]] = i } } // result = {123: 0, 124: 1} 这是去重重复后的元素 // reSet = {123: 2} 我们将重复的元素123作为key,它的下标2作为value。
4、上一步得到了result和reSet2个对象,那么,我们该用哪个对象来处理原数组的去重呢?只需要reSet,reSet记录了要去重的对象所在的下标,那么可以直接用splice干掉它。
for(let key in reSet){ arr.splice(reSet[key], 1) } /* arr = [{ _id: 123, name: '张三' },{ _id: 124, name: '李四' }] */
5、说明
关键的第3和4步,都是用对象来处理,这样做的好处是时间复杂度可以达到O(1),如果用数组来保存,则需要2个for循环,时间复杂度变成了O(n²)。
完整源码
function removeRepeat(arr, field){ let s = [], result = {}, reSet = {} for(let v of arr){ s.push(v[field]) } for(let i=0,len=s.length;i<len;i++){ if(!result[s[i]] && result[s[i]] !== 0) { result[s[i]] = i } else { reSet[s[i]] = i } } for(let key in reSet){ arr.splice(reSet[key], 1) } return arr } // removeRepeat(arr, '_id')
总结
数组还有各种有趣的操作,也经常作为各大公司考察的题型之重,多练习和数组相关的算法会很有帮助。
注:本文内容来自互联网,旨在为开发者提供分享、交流的平台。如有涉及文章版权等事宜,请你联系站长进行处理。