利用Underscore求數組的交集、并集和差集

1 數組交集函數——intersection

數組的交集是指包含多個數組中的共同元素的一個數組,求數組的交集就是找出給定數組中的共有元素。

下面實現一個求兩個數組交集的函數。

判斷數組是夠包含指定值,使用Array.indexOf就可以。所以我們可以遍歷第一個參數數組,然后使用Array.indexOf方法檢索第二個參數數組,如果第二個參數數組包含當前項,那么當前項即為兩個數組的交集元素,放入結果數組即可:

var intersection = function(arr1, arr2) {var length = arr1.length;var result = [];var i;for(i = 0; i < length; i++) {if(result.indexOf(arr1[i]) >= 0) continue;else {if(arr2.indexOf(arr1[i]) >= 0)result.push(arr1[i]);}}return result;
}
復制代碼

以上代碼實現了求兩個數組交集的功能。

如果涉及到多個數組呢?那就是Underscore的實現方法了。

以下是Underscore的源碼(附注釋):

// Produce an array that contains every item shared between all the
// passed-in arrays.
//獲取傳入的多個數組的交集,之所以只有一個形參,是因為該函數使用第一個數組參數作為基準。
_.intersection = function (array) {//將要返回的結果數組。var result = [];//傳入數組的個數。var argsLength = arguments.length;//遍歷第一個數組參數。for (var i = 0, length = getLength(array); i < length; i++) {//當前項。var item = array[i];//如果結果數組中已有該項,那么直接跳過當前循環,進入下一輪循環中。if (_.contains(result, item)) continue;var j;//從第二個參數開始,遍歷每一個參數。for (j = 1; j < argsLength; j++) {//一旦有一個參數數組不包含item,就退出循環。if (!_.contains(arguments[j], item)) break;}//如果所有參數數組都包含item項,就把item放入result。if (j === argsLength) result.push(item);}return result;
};
復制代碼

可以看到該函數一次接受多個數組,但是只有一個形參(array),該參數表示接收到的第一個數組,Underscore使用它作為參考,遍歷該數組,然后依次判斷剩余參數數組是否包含當前項,如果全部包含則該項為交集元素,推入結果數組當中。

2 數組并集函數——union

數組的并集是指包含指定的多個數組的所有元素的數組,求多個數組的并集即為求一個包含所有數組的所有元素的數組。

這里最直接的實現方法就是遍歷所有數組參數,然后針對數組的每一項,放入到結果數組中(如果已經存在于結果數組中那么久不再添加)。

var union = function() {var arrays = arguments;var length = arguments.length;var result = [];var i;for(i = 0; i < length; i++) {var arr = arrays[i];var arrLength = arrays[i].length;for(var j = 0; j < arrLength; j++) {if(result.indexOf(arr[j]) < 0) {result.push(arr[j]);}}}return result;
}
復制代碼

在閱讀Underscore源碼的時候,感覺它的實現方法十分巧妙。

Underscore中已經有了很多工具方法,所以可以拿來直接使用,比如restArgs、flatten、uniq。為什么強調這幾個方法呢?因為使用這幾個方法就可以實現數組求并集。

我們的union方法是接受多個數組作為參數的,而restArgs可以把多個數組參數合并到一個數組中作為參數;然后通過flatten函數,我們可以把得到的這個數組參數展開,展開之后得到的數組就是包含所有數組參數的所有元素的一個數組了,但是這個數組中有冗余項,我們必須對其進行去重;這時候使用我們的uniq工具函數就可以對其進行去重了。

經過這三個函數的處理,我們得到的數組就是多個數組參數的并集!

Underscore源碼:

// Produce an array that contains the union: each distinct element from all of
// the passed-in arrays.
_.union = restArgs(function (arrays) {return _.uniq(flatten(arrays, true, true));
});
復制代碼

這樣的實現是不是很簡介大氣?

3 數組差集函數——difference

數組的差集是指由數組A中所有不屬于數組B的元素所組成的一個數組。

直接的實現方法就是遍歷前者,然后判斷每個元素是否屬于后者,如果不屬于,那么就推入結果數組。

簡單實現:

var difference = function(arr1, arr2) {var length = arr1.length;var i;var result = [];for(i = 0; i < length; i++) {if(arr2.indexOf(arr1[i]) < 0) {result.push(arr1[i]);}}return result;
}
復制代碼

Underscore的實現(附注釋):

// Take the difference between one array and a number of other arrays.
// Only the elements present in just the first array will remain.
//數組求差集函數。
//通過restArgs函數把第二個數組開始的所有參數數組合并到一個數組。
_.difference = restArgs(function (array, rest) {//使用flatten展開rest數組。rest = flatten(rest, true, true);//使用filter函數過濾array數組達到求差集的目的,判斷條件就是value是否屬于rest。return _.filter(array, function (value) {return !_.contains(rest, value);});
});
復制代碼

更多Underscore源碼解析:GitHub

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

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

相關文章

RT-Thread簡介

RT-Thread簡介 RT-Thread是一款完全由國內團隊開發維護的嵌入式實時操作系統&#xff08;RTOS&#xff09;&#xff0c;具有完全的自主知識產權。 經過16個年頭的沉淀&#xff0c;伴隨著物聯網的興起&#xff0c;它正演變成一個功能強大、組件豐富的物聯網操作系統。 RT-Thre…

調用第三方API ,實現手機號碼歸屬地及運營商查詢

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 運行結果&#xff1a; 中國電信 西雙版納 西雙版納,中國電信 代碼&#xff1a; import java.io.BufferedReader; import java.io.I…

學成在線--21.課程信息修改

文章目錄一.需求分析二.課程管理導航頁面1.定義course_manage.vue為課程管理頁面2.創建各個信息管理頁面3.創建路由三.服務端1.Api接口1&#xff09;根據課程ID查詢課程信息2&#xff09;修改課程信息2.Dao3.Service4.Controller四.前端1. 完成course_baseinfo.vue頁面2.API方法…

HTTP協議特點

&#xff08;一&#xff09;HTTP協議是無狀態的。也就是說&#xff0c;同一個客戶第二次訪問同一個服務器上的頁面時&#xff0c;服務器的響應與第一次被訪問時相同。服務器不記得訪問過得這個用戶&#xff0c;也不記得為這個客戶服務過多少次。 &#xff08;二&#xff09;HT…

C#曲線分析平臺的制作(四,highcharts+ajax加載后臺數據)

在上一篇博客&#xff1a;C#曲線分析平臺的制作&#xff08;三&#xff0c;三層構架echarts顯示&#xff09;中已經完成了后臺的三層構架的簡單搭建&#xff0c;為實現后面的拓展應用開發和review 改寫提供了方便。而在曲線分析平臺中&#xff0c;往往有要求時間軸聯動功能&…

國際C語言混亂代碼大賽結果公布

國際C語言混亂代碼大賽&#xff08;IOCCC, The International Obfuscated C Code Contest&#xff09;是一項國際編程賽事&#xff0c;從1984年開始&#xff0c;每年舉辦一次&#xff08;1997年、1999年、2002年、2003年和2006年例外&#xff09;。目的是寫出最有創意的最讓人難…

JDBC連接數據庫(一)

原文地址http://www.cnblogs.com/hongten/archive/2011/03/29/1998311.html JDBC連接數據庫 創建一個以JDBC連接數據庫的程序&#xff0c;包含7個步驟&#xff1a; 1、加載JDBC驅動程序&#xff1a; 在連接數據庫之前&#xff0c;首先要加載想要連接的數據庫的驅動到JVM…

eclipse加速之禁用 JS、jsp 等文件的語法驗證

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 去除eclipse的JS驗證&#xff1a; 將windows->preference->Java Script->Validator->Errors/Warnings-> Enable Javascr…

學成在線--22.課程營銷

文章目錄一.需求分析二.數據模型三.服務端1.Api接口1&#xff09;查詢課程營銷信息2&#xff09;更新課程營銷信息2.Dao3.Service4.Controller四.前端1.Api 方法2.編寫 course_marketinfo.vue1&#xff09;template2&#xff09;數據對象3&#xff09;保存方法4&#xff09;在m…

電子郵件系統

&#xff08;一&#xff09;電子郵件系統的構成 1.用戶代理 用戶與電子郵件系統的接口&#xff0c;用戶代理使用戶能夠通過一個很友好的接口來發送和接收郵件&#xff0c;用戶代理就是一個運行在PC上的程序。 2 郵件服務器 郵件服務器的功能是發送和接收郵件&#xff0c;同…

面向對象的接口類 以及鴨子類型

1.接口類,抽象類. 2.鴨子類型(Python多態)(Python三大特性之一)Python封裝 1.接口類和抽象類只是在工作中書寫的一種規范. class QQ: def pay(self,money): print("使用QQ支付%s"%money) class Ali: def pay(self,money): print("使用支付寶支付%s"%money…

mysql查看binlog日志內容

2019獨角獸企業重金招聘Python工程師標準>>> &#xff08;一&#xff09; binlog介紹 binlog,即二進制日志,它記錄了數據庫上的所有改變&#xff0c;并以二進制的形式保存在磁盤中&#xff1b; 它可以用來查看數據庫的變更歷史、數據庫增量備份和恢復、Mysql的復制&…

架構師:我們需要頂層設計

架構師&#xff1a;我們需要頂層設計背景&#xff1a; 某公司&#xff0c;建立的程序又被推倒&#xff0c;外人覺得很奇怪&#xff0c;這個程序的主管非常敬業&#xff0c;關注到了程序每一個細節&#xff0c;甚至包括每一個按鈕的文字和位置。這個主管很委屈&#xff0c;他說…

文件傳輸協議FTP

文件傳輸協議FTP提供交互式的訪問&#xff0c;允許客戶指明文件的類型和格式&#xff0c;并允許文件具有存取權限。它屏蔽了個計算機系統的細節&#xff0c;因而適合于在異構網絡中任意計算機之間傳輸文件。它提供不同種類主機系統之間的文件傳輸能力&#xff0c;可以提供用戶對…

Centos7安裝Docker教程

1.首先安裝必要依賴&#xff1a; sudo yum install -y yum-utils device-mapper-persistent-data lvm22.然后添加倉庫源&#xff1a; sudo sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo3.最后安裝 Docker&#xff…

String.format() 方法用法解說

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 String chargeFlowUrl _AGENT_URL "?agentAccount" _AGENT_ACCOUNT "&sequence%s &phone%s &iceUrl%s &…

Choose unique values for the 'webAppRootKey' context-param in your web.xml files! 錯誤的解決

大意是Log4jConfigListener在獲取webapp.root值時&#xff0c;被后一context的值替換掉了&#xff0c;所以要在各個項目的web.xml中配置不同的webAppRootKey值&#xff0c;隨即在其中一個web.xml中添加&#xff1a; <context-param> <param-name>webAppRootKey<…

ionic3 cordova ionic-native插件

ionic-native插件 cordova安裝插件 以及 ionic-native插件使用過程以及步驟 cordova plugin add cordova-plugin-插件名稱。 //安裝插件npm install ionic-native/對應插件名稱 --save。 //寫入package.json在app.module.ts 的 providers 進行引用解釋&#xff1a;cordove plug…

Diango博客--19.使用 Docker部署項目到線上服務器

文章目錄1.克隆代碼到服務器2.創建環境變量文件用于存放項目敏感信息3.在 .production 文件寫入下面的內容并保存4.修改 Nginx 配置5.修改項目配置文件6.啟動容器7.檢查容器啟動狀況8.配置 HTTPS 證書&#xff08;沒有配置域名無法配置&#xff0c;只能通過服務器 ip 以 HTTP 協…

從一生的角度看程序員的學習和發展

很多人談學習和發展的時候&#xff0c;往往忽略人的先天自然條件&#xff0c;在這里我們從這個視角切入&#xff0c;來探討一下程序員一生的可能軌跡。 如果把程序員的人生分為三個階段&#xff0c;那么他們是&#xff1a; 畢業~30歲&#xff1a;這個時間段里&#xff0c;大多…