• 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

     
  • 相关阅读:
    最近积累的JS 东西,分享一下
    C#定时任务框架Quartz.NET
    如何成为微软社区MVP以及年终总结
    git 基于某个分支创建分支
    iframe跨域-Js通信的一种方式
    tcp连接建立断开过程及状态变化
    MySQL-InnoDB的事务隔离与锁
    MySQL索引原理总结
    php gd实现简单图片验证码与图片背景文字水印
    php 取post数据的三种方式
  • 原文地址:https://www.cnblogs.com/hao-1234-1234/p/11753973.html
Copyright © 2020-2023  润新知