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(n2)。

完整源碼


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

轉載于:https://www.cnblogs.com/lalalagq/p/9959426.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/249016.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/249016.shtml
英文地址,請注明出處:http://en.pswp.cn/news/249016.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

關于__getattribute__

先看一個案例 class Tree(object):def __init__(self,name):self.namenameself.cateplantdef __getattribute__(self, item):if item大樹:print(log 大樹)return 我愛大樹else:return object.__getattribute__(self,item)aaTree(rrrr) print(aa.name) print(aa.cate) 運行結果…

通過Navicat for MySQL遠程連接的時候報錯mysql 1130的解決方法

來源:互聯網 作者:佚名 時間:10-16 18:41:20 【大 中 小】 錯誤代碼是1130,ERROR 1130: Host xxx.xxx.xxx.xxx is not allowed to connect to this MySQL server 是無法給遠程連接的用戶權限問題 Navicat for mysql 1130錯誤 用…

Java Language Changes for Java SE 9

Java9引入了module模塊的概念,是類與接口和數據資源的一種封裝,并可以聲明與其他模塊的依賴關系。這里總結一下Java9帶來的新特性。更簡練的try-with-resources語句final Resource resource1 new Resource("resource1");//a final resourceRe…

ProtocolHandler繼承體系

轉載于:https://www.cnblogs.com/GooPolaris/p/10815072.html

mysql數據庫存儲過程及調用方法

mysql數據庫存儲過程及調用方法 mysql5.0以后就支持存儲過程了,目前mysql的6.0Alpha版也已經推出。6.0不僅支持大型數據庫如oracle等的絕大部分功 能,如存儲過程、視圖、觸發器、job等等,而且修正了這些功能所存在的bug,其中6.0.1…

紅蜻蜓

日本人なら一度は耳にしたことのある曲でしょう。忘れかけている里山の風景が目に浮かびます。このあたりは昔養蠶が盛んで、何処へ行っても桑畑があったものでしたが、最近はとんと見かけません。小さい頃、よく桑の実をつんで食べたものでした。(このあたりでは&q…

elastic學習筆記

要點 不同工具之間版本匹配很重要由點及面,先實踐起來再學細節的原理和使用 技術棧 laravel5.5框架scout組件elasticsearch6.3.0搜索引擎輔助 elasticsearch-head 查看集群數據可視化 中文分詞插件Ik介紹 laravel是一款現代化的php框架es是搜索引擎es-head是管理查看…

mysql 存儲過程中limit

mysql 存儲過程中limit 1、mysql的高版本(5.5),存儲過程中的limit可以使用變量,如下:select * from student limit iStart,iNum; 2、mysql的低版本(5.1),存儲過程中的limit不能使用…

高頻ES6

var promise new Promise((resolve, reject)> {if (操作成功) {resolve (value)}else{reject(error)} }) promise.than(function (value) {/*成功*/}, function(value) {/*失敗*/}) Promise是異步編程的一種解決方案, 比傳統的解決方案--回調函數和事件更加強大.由社區最早…

NodeJS+Express+MongoDB - 張果 - 博客園

目錄 一、MongoDB 1.1、安裝MongoDB 1.1.1、配置運行環境1.1.2、運行MongoDB1.2、數據庫操作 1.2.1、創建數據庫與查看數據庫1.2.2、刪除數據庫1.2.3、插入數據1.2.4、查詢數據1.2.5、修改1.2.6、刪除二、NodeJS訪問MongoDB 2.1、安裝MongoDB訪問驅動2.2、添加數據2.3、修改數…

一個好用的瀏覽器暗色瀏覽插件 Dark Reader

轉載于:https://www.cnblogs.com/tyong/p/9973363.html

Android小測驗感受

1.運行出現“...keeps stopping” 因為 前臺變量“無值”而后臺卻進行“獲取變量值” 2.switch(int,char...) case break;(不能忘) 3.轉載于:https://www.cnblogs.com/tangxx1996/p/10825134.html

SpringMVC ?注解式傳遞Ztree參數

前端頁面JS處理: $("#save").click( function(){var zTree $.fn.zTree.getZTreeObj("treeDemo" );if(projectType "" || projectType null || projectType undefined){alert( "請選擇項目類型!" ); return…

實驗 4 [bx]和 loop 的使用

實驗結論 實驗1:綜合使用 loop,[bx],編寫完整匯編程序,實現向內存 b800:07b8 開始的連續 16 個字單元重復填充字數據 0403H。 1.源代碼及實驗結果 運行結果:屏幕中央出現一排紅色的心?。 2.將源代碼程序中字數據 0403H→修改為 0…

linux開發工具之gcc

首先gcc編譯鏈接的一個實例如下所示: 接下來看一下gcc的常見選項: gcc的使用示例: 轉載于:https://www.cnblogs.com/wsw-seu/p/10826124.html

怎么解決eclipse報PermGen space異常的問題

怎么解決eclipse報PermGen space異常的問題 最近使用eclipse做開發,使用的服務器是tomcat,但在啟動時報了Caused by: java.lang.OutOfMemoryError: PermGen space的異常。 這個錯誤很常見,于是配置tomcat下的catalina.bat,配置e…

org.hibernate.service.ServiceRegistryBuilder被棄用

看視頻教程是這樣寫的: //創建配置對象Configuration config new Configuration().configure();//創建服務注冊對象ServiceRegistry serviceRegistry new ServiceRegistryBuilder().applySettings(config.getProperties()).buildServiceRegistry();//創建會話工廠對象session…

音頻基本概念

音頻基本概念 聲音的本質 音調:頻率 音量:振幅 音色:與材質有關,諧波(不規則的正玄波) 屏幕快照 2018-12-04 下午1.53.40.png采樣-量化-編碼 采樣大小: 一個采樣用多少bit存放,目前常…

How to use external classes and PHP files in Laravel Controller?

By: Povilas KoropLaravel is an MVC framework with its own folder structure, but sometimes we want to use something external which doesn’t follow the same structure. Let’s review two different scenarios – when we have external class and when it’s just a…

在多種瀏覽器中嵌入Applet

1 基本信息 摘要:一個開發好的Java Applet,是通過標準的標簽(Tag)嵌入到HTML頁面中的。瀏覽器在解析到支持的嵌入Applet的標簽時,會啟動Java Plug-in來渲染標簽中的Java Applet。 由于歷史原因,在頁面中嵌…