JS 對象 數組求並集,交集和差集


 

一、JS數組求並集,交集和差集

需求場景

最近,自己項目中有一些數組操作,涉及到一些數學集的運算,趁着完成后總結一下。

簡化問題之后,現有兩數組a = [1, 2, 3]b = [2, 4, 5],求a,b數組的並集,交集和差集。

方法選擇

JS在ES6,ES7之后,新增了一些數組方法,如果能夠使用,那是極好的,畢竟自己寫封裝函數還是比較辛苦的。

ES7

ES7新增了一個Array.prototype.includes的數組方法,用於返回一個數組是否包含指定元素,結合filter方法。

var boolean = array.includes(searchElement[, fromIndex])

  • // 並集
  • let union = a.concat(b.filter(v => !a.includes(v))) // [1,2,3,4,5]
  • // 交集
  • let intersection = a.filter(v => b.includes(v)) // [2]
  • // 差集
  • let difference = a.concat(b).filter(v => !a.includes(v) || !b.includes(v)) // [1,3,4,5]
js

ES6

ES6中新增的一個Array.from方法,用於將類數組對象和可遍歷對象轉化為數組。只要類數組有length長度,基本都可以轉化為數組。結合Set結構實現數學集求解。

Array.from(arrayLike[, mapFn[, thisArg]])

  • let aSet = new Set(a)
  • let bSet = new Set(b)
  • // 並集
  • let union = Array.from(new Set(a.concat(b))) // [1,2,3,4,5]
  • // 交集
  • let intersection = Array.from(new Set(a.filter(v => bSet.has(v)))) // [2]
  • // 差集
  • let difference = Array.from(new Set(a.concat(b).filter(v => !aSet.has(v) || !bSet.has(v)))) // [1,3,4,5]
js

ES5

ES5可以利用filter和indexOf進行數學集操作,但是,由於indexOf方法中NaN永遠返回-1,所以需要進行兼容處理。

  • 不考慮NaN(數組中不含NaN)
  • // 並集
  • var union = a.concat(b.filter(function(v) {
  • return a.indexOf(v) === -1})) // [1,2,3,4,5]
  • // 交集
  • var intersection = a.filter(function(v){ return b.indexOf(v) > -1 }) // [2]
  • // 差集
  • var difference = a.filter(function(v){ return b.indexOf(v) === -1 }).concat(b.filter(function(v){ return a.indexOf(v) === -1 })) // [1,3,4,5]
js
  • 考慮NaN
  • 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] : []) // [1,2,3,4,5]
  • // 交集
  • var intersection = a.filter(function(v){ return b.indexOf(v) > -1 }).concat(aHasNaN & bHasNaN ? [NaN] : []) // [2]
  • // 差集
  • 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] : []) // [1,3,4,5]
js

結語

由於JS語言的特殊性,NaN在數組的數學集操作中有不少問題,好在ES6和ES7中,新的數組方法解決了部分情況。單從簡潔性來看,ES7的方法最簡潔明了。

就是不知道新的標准要猴年馬月才能被各大瀏覽器兼容,目前還是使用Babel比較靠譜。

本文鏈接:https://excaliburhan.com/post/js-set-operation.html

 

二、js求對象數組的交集/並集/差集/去重

復制代碼
      1.求交集
    var arr1 = [{name:'name1',id:1},{name:'name2',id:2},{name:'name3',id:3}]; var arr1Id = [1,2,3] var arr2 = [{name:'name1',id:1},{name:'name2',id:2},{name:'name3',id:3},{name:'name4',id:4},{name:'name5',id:5}]; var result = arr2.filter(function(v){ return arr1Id.indexOf(v.id)!==-1 // 利用filter方法來遍歷是否有相同的元素 }) console.log(result);
復制代碼

 

復制代碼
      2.求並集
    let arr1 = [{name:'name1',id:1},{name:'name2',id:2},{name:'name3',id:3}]; let arr2 = [{name:'name1',id:1},{name:'name4',id:4},{name:'name5',id:5}]; let arr3 = arr1.concat(arr2); let result = []; var obj = []; result = arr3.reduce(function(prev, cur, index, arr) { console.log(prev, cur); obj[cur.id] ? '' : obj[cur.id] = true && prev.push(cur); return prev; }, []); console.log(result);
復制代碼

 

1
2
3
4
5
6
7
8
9
3.求差集< br >    let arr1 = [{name:'name1',id:1},{name:'name2',id:2},{name:'name3',id:3}];
   let arr1Id = [1,2,3];
   let arr2 = [{name:'name1',id:1},{name:'name4',id:4},{name:'name5',id:5}];
   let arr2Id = [1,4,5];
   let arr3 = arr1.concat(arr2);
   let result = arr3.filter(function(v){
       return arr1Id.indexOf(v.id)===-1 || (arr2Id.indexOf(v.id)===-1)
   })
   console.log(result);

  

復制代碼
      4.去重
    let arr = [{name:'name1',id:1},{name:'name2',id:2},{name:'name3',id:3},{name:'name1',id:1},{name:'name4',id:4},{name:'name5',id:5}]; var obj = []; let result = arr.reduce(function(prev, cur, index, arr) { console.log(prev, cur); obj[cur.id] ? '' : obj[cur.id] = true && prev.push(cur); return prev; }, []);
復制代碼

 實際組件中應用去重

 a方法
復制代碼
       let includeThis = false
            let vm = this
            if(vm.informedPersonList.length>0){
                vm.informedPersonList.forEach(el =>{
                    if(el.id == vm.selectedTrueItem.id){
                        includeThis = true
                    }
                })
            }
            if(includeThis===false){
                vm.informedPersonList.push(vm.selectedTrueItem)
            }else{
                Message({message: '請勿重復添加',type: 'warning'})
            }
復制代碼
 b方法(必須先let informedPersonL = vm.informedPersonList,不能直接使用vm.informedPersonList,否則瀏覽器控制台會報錯)
1
2
3
4
5
6
7
8
9
vm.informedPersonList.push(this.selectedTrueItem)
let obj = {};
let informedPersonL = vm.informedPersonList
informedPersonL = informedPersonL.reduce((cur,next) => {
     obj[next.id] ? "" : obj[next.id] = true && cur.push(next);
     return cur;
},[]) //設置cur默認類型為數組,並且初始值為空的數組
vm.selectedTrueItem = {}
vm.$emit("backInformedPList",informedPersonL);

  

 來源:https://www.cnblogs.com/cx709452428/p/10180807.html
以為兩個數組都是對象數組怎么辦?
先獲取某個數組根據某屬性去重后的值classArr。 然后在
 let arr1ID= arrayObjectDistinctReturnKey(arr, "id");
然后
 var arr2 = [{name:'name1',id:1},{name:'name2',id:2},{name:'name3',id:3},{name:'name4',id:4},{name:'name5',id:5}];
 var result = arr2.filter(function(v){
            return arr1Id.indexOf(v.id)!==-1 // 利用filter方法來遍歷是否有相同的元素
 })
//去重方法
 function arrayObjectDistinctReturnKey(arr, key) {
     // console.log('arr', arr)
     var result = []
     var obj = {}
     for (var i = 0; i < arr.length; i++) {
         if (arr[i][key]) {
             if (!obj[arr[i][key]]) {
                 result.push(arr[i][key])
                 obj[arr[i][key]] = true
             }
         }
     }
     // console.log('result', result)
     return result
 }

 js去重相關文章: https://www.cnblogs.com/hao-1234-1234/p/11122383.html

 


免責聲明!

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



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