Skip to content

阿里算法题:编写一个函数计算多个数组的交集 #10

Open

Description

@sisterAn

要求:
输出结果中的每个元素一定是唯一的

Activity

  1. changed the title [-]阿里算法题:求多个数组之间的交集[/-] [+]阿里算法题:编写一个函数计算多个数组的交集[/+] on Apr 7, 2020
  2. wuchendi commented on Apr 7, 2020

    @wuchendi
    var intersection = function (nums1, nums2) {
      let arr1 = Array.from(new Set(nums1));
      let arr2 = Array.from(new Set(nums2));
      let arr3 = new Array();
      for (let [v, k] of arr1.entries()) {
        if (arr2.includes(k)) {
          arr3.push(k)
        }
      }
      return arr3;
    };
    // 忽略我的命名......
  3. cyndra0 commented on Apr 7, 2020

    @cyndra0
    const intersection = (arrs) => {
    
      /** @returns { Set } intersection 两个集合的交集*/
      const intersectTwoSets = (set1, set2) => {
        const result = new Set(set1)
        for (let item of result) {
          if (!set2.has(item)) {
            result.delete(item)
          }
        }
        return result
      }
    
      /** @description 所有数组的交集 */
      const resultSet = (
        arrs
          .map(arr => new Set(arr))
          // O(N * M)
          .reduce(intersectTwoSets) 
      )
    
      return Array.from(resultSet)
    }
  4. liwuhou commented on Apr 8, 2020

    @liwuhou

    万能的reduce

    const getIntersection = (...arrs) => {
        return Array.from(new Set(arrs.reduce((total, arr) => {
            return arr.filter(item => total.includes(item));
        })));
    }
  5. mingju0421 commented on Apr 8, 2020

    @mingju0421
    function intersect(arrs) {
          let obj = {},
            result = {};
          for (let i = 0; i < arrs[0].length; i++) {
            obj[i] = 1;
          }
          for (let i = 1; i < arrs.length; i++) {
            result = {};
            arrs[i].forEach(element => {
              obj[element] ? (result[element] = 1) : "";
            });
            obj = result;
          }
    
          return Object.keys(obj);
        }
  6. 352800205 commented on Apr 8, 2020

    @352800205

    一行代码搞定

    let intersection = (list , ...args) => list.filter( item => args.every( list => list.includes( item )))
    console.log( intersection( [ 2,1 ], [ 2,3 ] ) ) // [ 2 ]
    console.log( intersection( [ 2,1 ], [ 4,3 ] ) ) // [ ]
  7. BoswellJi commented on Apr 8, 2020

    @BoswellJi
    /**
     * 编写一个函数计算多个数组的交集,要求结果中的每个元素都是唯一的
     */
    
    function multArrMerge() {
      let arrs = Array.prototype.slice.call(arguments).map(item => Array.from(new Set(item)));
      let shortArr = arrs[0];
      let mergeArr = [];
    
      // O(n)
      // 找到最短数组
      arrs.forEach((item, index) => {
        if (shortArr.length > item.length) {
          shortArr = item;
        }
      });
    
      // O(n^2)
      // 收集最短数组中每个元素的交集
      mergeArr = shortArr.map(item => {
        const temp = [];
        arrs.forEach(item1 => {
          if (item1.indexOf(item) > -1) {
            temp.push(item);
          }
        });
        return temp;
      });
    
      // O(n)
      // 过滤每个数组的交集
      mergeArr = mergeArr.map(item => {
        if (item.length === arrs.length) {
          return item[0];
        }
      }).filter(item => item)
    
      return mergeArr;
    }
    
    function multArrMerge(...arrs) {
      arrs = arrs.map(item => Array.from(new Set(item)));
      let targetArr = arrs[0];
      for (let i = 1, len = arrs.length; i < len; i++) {
        targetArr = arrs[i].filter(item => targetArr.includes(item));
      }
      return targetArr;
    }
    
  8. ZWBruce commented on Apr 8, 2020

    @ZWBruce
    function intersection(arr,...args){
      // 记录每次对比两个数组的交集
      let set = new Set(arr);
      for(let e of args){ // 取出不定个参数数组
        let rep = []; // 记录当前数组和之前交集的交集
        for(let ele of e){
          if(set.has(ele)){
            rep.push(ele);
          }
        }
        set = new Set(rep); // 将交集用于和下组数组的对比
      }
      return [...set];
    }
    
  9. AiKunnnnn commented on Apr 8, 2020

    @AiKunnnnn

    在原先两个数组求交集的基础上使用reduce

    function intersect(nums1,nums2){
       return [...new Set(nums1.filter((item)=>nums2.includes(item)))]
    }
    
    function intersectAll(...arrs){
        return resultArr = arrs.reduce(function(prev,cur){
    	return intersect(prev,cur);
        })
    }
    

    合并之后就是

    function getIntersect(...arrs) {
        return arrs.reduce(function(prev,cur){
    	return [...new Set(cur.filter((item)=>prev.includes(item)))]
        })
    }
    
  10. kimixue commented on Apr 8, 2020

    @kimixue
    const mixed = (...arrs) => {
      return [...new Set(arrs.reduce((sum,arr) => {
        return arr.filter(i => sum.includes(i));
      }))]
    }
    
  11. hh-cheng commented on Apr 8, 2020

    @hh-cheng
    function intersection(...arr) {
        let result = [];
        arr.forEach(arr => {
            if( arr instanceof Array ){
                // 如果是第一个数组,则直接将该数组去重然后 push 到目标数组中
                if( !result.length ) {
                    result.push(...new Set(arr));
                    return ;
                }
                // 如果是第二个及以后的数组,则先去重然后用目标数组过滤
                const tempSet = new Set(arr);
                result = result.filter(item=>tempSet.has(item));
            }
        });
        return result;
    }
  12. hecun0000 commented on Apr 8, 2020

    @hecun0000
    var intersection = function (...arrs) {
      let res= arrs[0]
      for (let i = 1; i < arrs.length; i++) {
        res = res.filter(item=> arrs[i].includes(item))    
      }
      return [...new Set(res)]
    }
  13. hhshii commented on Apr 8, 2020

    @hhshii
    function intersection(){
      return Array.prototype.slice.call(arguments).reduce((arr, item) => {
            return item.filter(key => arr.includes(key));
      })
    }
  14. sisterAn commented on Apr 8, 2020

    @sisterAn
    OwnerAuthor

    使用 reducer 函数

    const intersection = function(...args) {
        if (args.length === 0) {
        return []
      }
      if (args.length === 1) {
        return args[0]
      }
      return [...new Set(args.reduce((result, arg) => {
        return result.filter(item => arg.includes(item))
      }))]
    };
  15. sfsoul commented on Apr 27, 2020

    @sfsoul
    const intersection = function(...rest) {
            console.log('rest', rest);
            const arr = rest.reduce((prev, next) => {
                console.log('prev', prev);
                console.log('next', next);
                if (prev.length === 0) {
                    prev = prev.concat(next);
                } else {
                    // prev = [...new Set(prev.filter(item => next.includes(item)))]; 每次计算 prev 值都会进行一次去重
                    prev = prev.filter(item => next.includes(item));
                }
                return prev;
            }, []);
            return [...new Set(arr)]; // 不如计算完之后统一去一次重
        };
    
  16. 2 remaining items

  17. guanping1210 commented on Jun 1, 2020

    @guanping1210

    需要注意的地方:
    1、交集中的每一项,在每个数组中都要存在,所以用到了every
    2、需要考虑去重,有可能一个数据在每个数组中多次出现

        const intersection = function(list, ...args) {
                return [
                    ...new Set(list.filter(item => args.every(temp => temp.includes(item))))
                ]
            }
        intersection([2,1,2], [3], [2,5,6,6,3]) // []
        intersection([2,1,2], [1,2,3], [2,5,6,6,3]) // [2]
    
  18. scottdao commented on Jun 23, 2020

    @scottdao

    function merge(){
    let args = Array.prototype.slice.call(arguments);
    let col = 0, new_obj = {}, len = args.length, new_arr = [];
    while(col<args.length){
    let row = args[col].length - 1,cache_arr = [];
    while(row>=0){
    if(new_obj[args[col][row]]){
    new_obj[args[col][row]] = ++new_obj[args[col][row]];
    }else{
    new_obj[args[col][row]] = 1;
    }
    // console.log(new_obj, args[col][row])
    if(new_obj[args[col][row]]>=len){
    cache_arr.push(args[col][row])
    }
    row--;
    new_arr = cache_arr;
    }
    col++
    }
    // console.log(new_obj)
    return new_arr;
    }

  19. Been101 commented on Jul 15, 2020

    @Been101

    1

    function twoIntersection(p, n) {
      const map = {}
      const res = []
      p.forEach((key) => {
        map[key] = 1
      })
    
      n.forEach((key) => {
        if (map[key]) {
          map[key]++
          if (map[key] === 2) {
            res.push(key)
          }
        }
      })
      return res
    }
    
    const intersection = (...arrs) => arrs.reduce(twoIntersection)

    2

    const intersection = (first, ...rest) => [
      ...new Set(first.filter((item) => rest.every((arr) => arr.includes(item)))),
    ]
  20. qianlongo commented on Aug 15, 2020

    @qianlongo
    const intersection2 = (...arrays) => {
      if (arrays.length === 0) {
        return []
      }
    
      if (arrays.length === 1) {
        return arrays[ 0 ]
      }
    
      return [ ...new Set(arrays.reduce((result, array) => {
        return result.filter((it) => array.includes(it))
      }))]
    }
  21. jwliushaoye commented on Aug 26, 2020

    @jwliushaoye
        function intersection (arrays) {
                let result = []
                let resMap = {}
                let tempArrays = arrays.flat(2)
                for (let num of tempArrays) {
                    if (resMap[num]) {
                        result.push(num)
                    } else {
                        resMap[num] = num
                    }
                }
                return [...new Set(result)]
            }
  22. DAHU123 commented on Feb 2, 2021

    @DAHU123

    `
    function intersection(arr1, arr2) {
    const a1 = new Set([...arr1]);
    return Array.from(new Set([...arr2.filter(item => a1.has(item))]));
    }

    `

  23. emmachan613 commented on Mar 18, 2021

    @emmachan613
    function intersection(arrs) {
      function intersectionTwo(nums1, nums2) {
        return Array.from(new Set(nums1.filter(v => nums2.includes(v))))
      }
      return arrs.reduce(intersectionTwo)
    }
  24. liuchao1618 commented on Mar 24, 2021

    @liuchao1618

    // 多个数组取交集(三个及以上)
    // 原数组
    const serveralArr = [
    [1,2,4,5,23,3,2,2,4,3,5,5],
    [3,2,3,2,2,4,3,1,4,5,6],
    [3,2,4,3,2,4,1,2,5],
    [3,2,4,5,5,4,3,1,2,2],
    [3,2,23,3,4,1,3,4,5,5,4,3,1,2,2],
    [3,2,4,1,2,5,5,4,3,1,2,2],
    [3,2,4,25,5,4,3,1,2,2],
    ]
    // ES5 方法实现数学意义上的交集结果
    const intersectNoRepeatFirst = serveralArr => {
    let minArr = serveralArr[0]
    serveralArr.forEach(item => {
    if(item.length < minArr.length){
    minArr = item
    }
    })
    const result = []
    minArr.forEach(item => {
    serveralArr.forEach(j => {
    if(j.includes(item) && !result.includes(item)){
    result.push(item)
    }
    })
    })
    return result
    }
    // ES6 方法实现数学意义上的交集结果
    const intersectNoRepeatTwice = arrs => {
    return arrs.reduce(function(prev,cur){
    // return [...new Set(cur.filter((item)=>prev.includes(item)))]
    return Array.from(new Set(cur.filter((item)=>prev.includes(item))))
    })
    }
    // 输出数学意义上的交集结果
    console.log(intersectNoRepeatFirst(serveralArr), intersectNoRepeatTwice(serveralArr)) // => (5) [3, 2, 4, 1, 5]; (5) [3, 2, 4, 5, 1]
    // ES5 方法实现有重复元素的交集结果
    const intersectRepeat = arr => {
    const result = []
    const tempArr = []
    arr.forEach(item => {
    const obj = {}
    item.forEach(j => {
    if(obj.hasOwnProperty(j)){
    obj[j] += 1
    }else{
    obj[j] = 1
    }
    })
    tempArr.push(obj)
    })
    let arrr = tempArr[0]
    tempArr.forEach(item => {
    if(item.length < arrr.length){
    arrr = item
    }
    })
    const newOjb = {}
    Object.keys(arrr).forEach(item => {
    newOjb[item] = Math.min.apply(Math, tempArr.map(function(o) {return o[item]}))
    })
    Object.keys(newOjb).forEach(item => {
    if(newOjb[item]){
    for(let i = 0; i < newOjb[item]; i++){
    result.push(Number(item))
    }
    }
    })
    return result
    }
    // 输出有重复元素的交集结果
    console.log(intersectRepeat(serveralArr)) // => (9) [1, 2, 2, 2, 3, 3, 4, 4, 5]

  25. ccloveak commented on Dec 3, 2021

    @ccloveak

    万能的reduce

    const getIntersection = (...arrs) => {
        return Array.from(new Set(arrs.reduce((total, arr) => {
            return arr.filter(item => total.includes(item));
        })));
    }

    It's helpful for me.

  26. whenTheMorningDark commented on Feb 21, 2022

    @whenTheMorningDark
    function getArr(...argument) {
          if (argument.length === 0) {
            return []
          }
          return calc(argument)
        }
    
        function calc(arr) {
          const len = arr.length
          if (len === 1) {
            return arr[0]
          }
          const mid = Math.floor(len / 2)
          const right = arr.slice(0, mid)
          const left = arr.slice(mid, len)
          return calcTwo(calc(right), calc(left))
        }
    
        function calcTwo(arr1, arr2) {
          const len1 = arr1.length
          const len2 = arr2.length
          if (len2 > len1) {
            [arr1, arr2] = [arr2, arr1]
          }
          return Array.from(new Set(arr1.filter(v => arr2.includes(v))))
        }
  27. emmachan613 commented on Feb 21, 2022

    @emmachan613
  28. lyllovelemon commented on Feb 21, 2022

    @lyllovelemon
  29. seyeeL commented on Nov 17, 2022

    @seyeeL
  30. emmachan613 commented on Nov 17, 2022

    @emmachan613
  31. lyllovelemon commented on Nov 17, 2022

    @lyllovelemon
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions