Javascript系列——对象元素的数组去重实现
概要
这是一篇记录文,记录数组操作对象去重的实现。
需求
有这样一个数组
[{
_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')
补充
受到各路大神的解法影响,我也针对上面代码的不足做了修改。
1、更简洁的代码。
2、支持多个重复对象的去重,缺点是会改变原来的排序。
const removeRepeat = (arr, field) => {
let s = {}
for(let i=0,len=arr.length;i<len;i++){
s[arr[i][field]] = arr[i]
}
return Object.values(s)
}
总结
数组还有各种有趣的操作,也经常作为各大公司考察的题型之重,多练习和数组相关的算法会很有帮助。
原文地址:https://segmentfault.com/a/1190000012873968
Javascript系列——对象元素的数组去重实现的更多相关文章
- JavaScript学习系列博客_28_JavaScript 数组去重
数组去重 var arr = [1,2,3,2,2,1,3,4,2,5]; //去除数组中重复的数字 //获取数组中的每一个元素 for(var i=0 ; i<arr.length ; i++ ...
- JavaScript系列-----对象基于哈希存储(<Key,Value>之Key篇) (1)
1.Hash表的结构 首先,允许我们花一点时间来简单介绍hash表. 1.什么是hash表 hash表是一种二维结构,管理着一对对<Key,Value>这样的键值对,Hash表的结构如下图 ...
- JavaScript常见的五种数组去重的方式
▓▓▓▓▓▓ 大致介绍 JavaScript的数组去重问题在许多面试中都会遇到,现在做个总结 先来建立一个数组 var arr = [1,2,3,3,2,'我','我',34,'我的',NaN,NaN ...
- JavaScript系列-----对象基于哈希存储(<Key,Value>之Value篇) (3)
JavaScript系列-----Objectj基于哈希存储<Key,Value>之Value 1.问题提出 在JavaScript系列-----Object之基于Hash<Key, ...
- javascript高逼格代码实现数组去重,JSON深度拷贝,匿名函数自执行,数字取整等
1.如何装逼用代码骂别人傻逼 (!(~+[])+{})[--[~+""][+[]]*[~+[]] + ~~!+[]]+({}+[])[[~!+[]]*~+[]] 2.如何优雅的用代 ...
- 重学ES系列之Set实现数组去重、交集、并集、差集
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 关于JavaScript中省略元素对数组长度的影响
在学习<JavaScript权威指南>第六版的第7.1节中通过数组直接量创建数组时,我们可以不给数组的某个元素赋值,它就会使undefined.虽然是undefined,但我们调用数组对象 ...
- js 数组判断是否包含某元素 或 数组去重
判断包含: 1.借助 jquery $.inArray(obj.UNIVERSITY_NAME, arryDatas) < 0var arr = [ "xml", &quo ...
- JS对以对象组成的数组去重
这是从https://segmentfault.com/q/1010000006954351参考的,达到了我要去重的功能!!! var hash = {};//arr是要去重的对象数组 arr = a ...
随机推荐
- JavaScript 实现留言框
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- 单元测试Struts2的Action(包含源码)
很久没有从头搭建Struts2的环境了.最近,认真实践了单元测试Struts2.Spring等Java项目. 今天特意写的是单元测试Struts2的Action,遇到了不少问题,果然是实践出真知啊. ...
- https的基本原理,看完你的程序员女朋友再也不和你提分手了
[http风险] 首先,我们来讲一下平时上网的时候,存在的风险. 初步接触过网络的同学都知道,网络上是很不安全的,尤其是各种公共场合的免费WIFI,以及手机上各种免费上网的万能钥匙.这些不安全因素会导 ...
- linux环境下删除包含特殊字符的文件或目录
linux环境下删除包含特殊字符的文件或目录 ls -liUse find command as follows to delete the file if the file has inode nu ...
- BZOJ——1787: [Ahoi2008]Meet 紧急集合
http://www.lydsy.com/JudgeOnline/problem.php?id=1787 题目描述 输入 输出 样例输入 6 4 1 2 2 3 2 4 4 5 5 6 4 5 6 6 ...
- Unsupported major.minor version 51.0问题的解决
在java编程的过程中,当用myeclipse软件打开别人写的代码时,遇到Unsupported major.minor version 51.0此类问题,实在是令人痛苦不堪.弄了整整一晚才搞清楚,我 ...
- Extjs4.2 ajax请求url中传中文參数乱码问题
今天有个需求须要在url中传入中文參数.结果在后台取得时出现乱码,怀疑可能是编码问题.上网查询了资料,试了几种办法.发现有一种可行,记录在此,以便查阅. url中用encodeURI 进行2次编码: ...
- node08---Express框架
一.Express框架 Express框架是后台的Node框架,所以和jQuery.zepto.yui(雅虎的).bootstrap都不一个东西. Express在后台的受欢迎的程度,和jQuery一 ...
- MongoDB数据查询详解
查询全部 db.infos.find(); db.infos.find({"url":"www.baidu.com"}); id不要显示出来 db.info ...
- Linux下iscsi的使用
查看是否已安装了iscsi-initiator: [root@test\ ~]# rpm -qa |grep iscsi iscsi-initiator-utils-6.2.0.868-0.18.e ...