Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
sisterAn opened this issue Apr 7, 2020 · 30 comments
Open

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

sisterAn opened this issue Apr 7, 2020 · 30 comments
Labels

Comments

@sisterAn
Copy link
Owner

sisterAn commented Apr 7, 2020

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

@sisterAn sisterAn changed the title 阿里算法题:求多个数组之间的交集 阿里算法题:编写一个函数计算多个数组的交集 Apr 7, 2020
@WuChenDi
Copy link

WuChenDi commented Apr 7, 2020

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;
};
// 忽略我的命名......

@cyndra0
Copy link

cyndra0 commented Apr 7, 2020

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)
}

@liwuhou
Copy link

liwuhou commented Apr 8, 2020

万能的reduce

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

@mingju0421
Copy link

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);
    }

@352800205
Copy link

一行代码搞定

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 ] ) ) // [ ]

@BoswellJi
Copy link

BoswellJi commented Apr 8, 2020

/**
 * 编写一个函数计算多个数组的交集,要求结果中的每个元素都是唯一的
 */

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;
}

@ZWBruce
Copy link

ZWBruce commented Apr 8, 2020

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];
}

@KFCVme50-CrazyThursday
Copy link

KFCVme50-CrazyThursday commented Apr 8, 2020

在原先两个数组求交集的基础上使用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)))]
    })
}

@kimixue
Copy link

kimixue commented Apr 8, 2020

const mixed = (...arrs) => {
  return [...new Set(arrs.reduce((sum,arr) => {
    return arr.filter(i => sum.includes(i));
  }))]
}

@kizuner-bonely
Copy link

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;
}

@hecun0000
Copy link

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)]
}

@hhshii
Copy link

hhshii commented Apr 8, 2020

function intersection(){
  return Array.prototype.slice.call(arguments).reduce((arr, item) => {
        return item.filter(key => arr.includes(key));
  })
}

@sisterAn
Copy link
Owner Author

sisterAn commented Apr 8, 2020

使用 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))
  }))]
};

@sfsoul
Copy link

sfsoul commented Apr 27, 2020

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)]; // 不如计算完之后统一去一次重
    };

@sisterAn sisterAn added the 阿里 label May 5, 2020
@george-wq
Copy link

var intersection = function() {
console.log(arguments);
const setList = [...new Set(arguments[0])];
const list = [];
setList.forEach(num => {
let tag = true;
for (let i = 1; i < arguments.length; i++) {
if (!arguments[i].includes(num)) {
tag = false;
break;
}
}
if (tag) {
list.push(num);
}
});
return list;
}

  console.log(intersection([1,2,4, 5], [1,5,6,7], [1,3,5,6,8]));

@guanping1210
Copy link

需要注意的地方:
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]

@scottdao
Copy link

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;
}

@Been101
Copy link

Been101 commented Jul 15, 2020

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)))),
]

@qianlongo
Copy link

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))
  }))]
}

@jwliushaoye
Copy link

    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)]
        }

@DAHU123
Copy link

DAHU123 commented Feb 2, 2021

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

`

@emmachan613
Copy link

emmachan613 commented Mar 18, 2021

function intersection(arrs) {
  function intersectionTwo(nums1, nums2) {
    return Array.from(new Set(nums1.filter(v => nums2.includes(v))))
  }
  return arrs.reduce(intersectionTwo)
}

@liuchao1618
Copy link

// 多个数组取交集(三个及以上)
// 原数组
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]

@ccloveak
Copy link

ccloveak commented Dec 3, 2021

万能的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.

@whenTheMorningDark
Copy link

whenTheMorningDark commented Feb 21, 2022

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))))
    }

@emmachan613
Copy link

emmachan613 commented Feb 21, 2022 via email

@lyllovelemon
Copy link

lyllovelemon commented Feb 21, 2022 via email

@seyeeL
Copy link

seyeeL commented Nov 17, 2022

编写一个函数计算多个数组的交集 | 前端瓶子君
reducer 多打了一个 r

@emmachan613
Copy link

emmachan613 commented Nov 17, 2022 via email

@lyllovelemon
Copy link

lyllovelemon commented Nov 17, 2022 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests