zoukankan      html  css  js  c++  java
  • 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

    -------------------------------------------

    个性签名:独学而无友,则孤陋而寡闻。做一个灵魂有趣的人!

    如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!

    万水千山总是情,打赏一分行不行,所以如果你心情还比较高兴,也是可以扫码打赏博主,哈哈哈(っ•̀ω•́)っ✎⁾⁾!

  • 相关阅读:
    从缓冲上看阻塞与非阻塞socket在发送接收上的区别
    关于TCP封包、粘包、半包
    CURL 和LIBCURL C++代码 上传本地文件,好不容易碰到了这种折腾我几天的代码
    Spring boot 搭配 JPA 生成表注释 和 字段注释
    Spring Data JPA 中常用注解
    SpringBoot Data JPA 关联表查询的方法
    Spring boot data JPA数据库映射关系 : @OneToOne,@OneToMany,@ManyToMany
    Spring Boot Jpa 表名小写转大写
    SpringBoot入门系列~Spring-Data-JPA自动建表
    使用Spring-Session共享使用Session
  • 原文地址:https://www.cnblogs.com/mahmud/p/10349903.html
Copyright © 2011-2022 走看看