js數組並集,交集,差集


 

js數組並集,交集,差集的計算方式匯總

一、

new Set 方式實現

這種方式實現起來比較簡單,原理就是參考new Set可以去重的功能 ,關於去重可以點擊 https://www.haorooms.com/post/qd_ghfx 第17條。

new Set取並集

我封裝了一個函數,可以取傳入所有數組的並集,函數如下:

 //並集 function unionArray(a,b){ let tempArray = []; for(let i = 0;i<arguments.length;i++){ tempArray.push(...new Set(arguments[i])) } return [... new Set(tempArray)] }

使用如下:

 unionArray([1,2,3,4],[3,4,5,6],[8,8,7,7,6,6,5,5,4,4,3,3]) //(8) [1, 2, 3, 4, 5, 6, 8, 7]

new Set取交集

這里也是取2個數組的交集,多的可以自己擴展

 //交集 function intersect(a,b){ let set1 = new Set(a),set2 = new Set(b); return [...new Set([...set1].filter( x => set2.has(x)))]; }

使用方式如下:

intersect([1,2,3,4],[3,4,5,6]) //(2) [3, 4]

new Set取差集

我這里只是取2個數組的差集,多的大家可以自行擴展。

 function difference(a,b){ let set1 = new Set(a),set2 = new Set(b); return [...new Set([...set1].filter(x => !set2.has(x))),...new Set([...set2].filter(x => !set1.has(x)))]; }

用法如下:

difference([1,2,3,4],[3,4,5,6]) //(4) [1, 2, 5, 6]

二、include 方式實現

include方式我之前寫過取交集和差集的方式:https://www.haorooms.com/post/es6_string_object_array

今天簡單再來列舉一下吧:

include取並集

function unionArray(a,b){ let tempArr = a.slice() ; b.forEach(v => {!tempArr.includes(v) && tempArr.push(v)}) //tempArr=[1,2,3,4] return tempArr }

用法和上面一樣,傳2個數組就可以取其並集

unionArray([1,2,3,4],[3,4,5,6]); //(6) [1, 2, 3, 4, 5, 6]

include方式 數組a和數組b的交集:

 a.filter(v => b.includes(v))

include方式 數組a和數組b的差集:

a.concat(b).filter(v => !a.includes(v) || !b.includes(v))

函數自己封裝哈,一句話

三、 es5的方式實現

上面的方式用的是ES6,下面我們用ES5實現一下! filter可以實現簡單的去重,因此,實現並集也很簡單,把數組push到一起(或者連接到一起concat),去重就可以實現並集了。

[1,3,4,5,1,2,3,3,4,8,90,3,0,5,4,0].filter(function(elem,index,Array){ return index === Array.indexOf(elem); })

當然也可以用indexOf的方式(注:indexOf要考慮NAN或者不考慮NAN 2種情況)

//不考慮NAN var union = a.concat(b.filter(function(v) { return a.indexOf(v) === -1})) //考慮可以這么寫 var aHasNaN = a.some(function(v){ return isNaN(v) }) var bHasNaN = b.some(function(v){ return isNaN(v) }) var union = a.concat(b.filter(function(v) { return a.indexOf(v) === -1 && !isNaN(v)})).concat(!aHasNaN & bHasNaN ? [NaN] : [])

交集和差集可以模仿上面include方式,把include改成indexOf

indexOf方式 數組a和數組b的交集:

不考慮NaN(數組中不含NaN)

 a.filter(v => b.indexOf(v)!=-1)

考慮的話如下:

var aHasNaN = a.some(function(v){ return isNaN(v) }) var bHasNaN = b.some(function(v){ return isNaN(v) }) a.filter(function(v){ return b.indexOf(v) > -1 }).concat(aHasNaN & bHasNaN ? [NaN] : [])

indexOf方式 數組a和數組b的差集:

不考慮NaN(數組中不含NaN)

 a.concat(b).filter(v => a.indexOf(v) ==-1 || b.indexOf(v)==-1)

考慮的話如下:

var aHasNaN = a.some(function(v){ return isNaN(v) }) var bHasNaN = b.some(function(v){ return isNaN(v) }) var difference = a.filter(function(v){ return b.indexOf(v) === -1 && !isNaN(v) }).concat(b.filter(function(v){
return a.indexOf(v) === -1 && !isNaN(v) })).concat(aHasNaN ^ bHasNaN ? [NaN] : [])

四、原始方式,假如要兼容IE9及以下版本,可以考慮

function array_remove_repeat(a) { // 去重 var r = []; for(var i = 0; i < a.length; i ++) { var flag = true; var temp = a[i]; for(var j = 0; j < r.length; j ++) { if(temp === r[j]) { flag = false; break; } } if(flag) { r.push(temp); } } return r; } function array_intersection(a, b) { // 交集 var result = []; for(var i = 0; i < b.length; i ++) { var temp = b[i]; for(var j = 0; j < a.length; j ++) { if(temp === a[j]) { result.push(temp); break; } } } return array_remove_repeat(result); } function array_union(a, b) { // 並集 return array_remove_repeat(a.concat(b)); } function array_difference(a, b) { // 差集 a - b //clone = a var clone = a.slice(0); for(var i = 0; i < b.length; i ++) { var temp = b[i]; for(var j = 0; j < clone.length; j ++) { if(temp === clone[j]) { //remove clone[j] clone.splice(j,1); } } } return array_remove_repeat(clone); }

另外寫一下多維數組轉為一維數組的簡單方式

var arr = [1,[2,[[3,4],5],6]]; function unid(arr){ var arr1 = (arr + '').split(',');//將數組轉字符串后再以逗號分隔轉為數組 var arr2 = arr1.map(function(x){ return Number(x); }); return arr2; } console.log(unid(arr));

 

參考:https://www.haorooms.com/post/js_array_jiaojicjbj


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM