sisterAn / JavaScript-Algorithms

基础理论+JS框架应用+实践,从0到1构建整个前端算法体系
5.49k stars 633 forks source link

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

Open sisterAn opened 4 years ago

sisterAn commented 4 years ago

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

WuChenDi commented 4 years ago
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 commented 4 years ago
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 commented 4 years ago

万能的reduce

const getIntersection = (...arrs) => {
    return Array.from(new Set(arrs.reduce((total, arr) => {
        return arr.filter(item => total.includes(item));
    })));
}
mingju0421 commented 4 years ago
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 commented 4 years ago

一行代码搞定

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 commented 4 years ago
/**
 * 编写一个函数计算多个数组的交集,要求结果中的每个元素都是唯一的
 */

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 commented 4 years ago
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 commented 4 years ago

在原先两个数组求交集的基础上使用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 commented 4 years ago
const mixed = (...arrs) => {
  return [...new Set(arrs.reduce((sum,arr) => {
    return arr.filter(i => sum.includes(i));
  }))]
}
kizuner-bonely commented 4 years ago
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 commented 4 years ago
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 commented 4 years ago
function intersection(){
  return Array.prototype.slice.call(arguments).reduce((arr, item) => {
        return item.filter(key => arr.includes(key));
  })
}
sisterAn commented 4 years ago

使用 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 commented 4 years ago
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)]; // 不如计算完之后统一去一次重
    };
george-wq commented 4 years ago

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 commented 4 years ago

需要注意的地方: 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 commented 4 years ago

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 commented 4 years ago

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 commented 4 years ago
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 commented 4 years ago
    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 commented 3 years ago

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

`

emmachan613 commented 3 years ago
function intersection(arrs) {
  function intersectionTwo(nums1, nums2) {
    return Array.from(new Set(nums1.filter(v => nums2.includes(v))))
  }
  return arrs.reduce(intersectionTwo)
}
liuchao1618 commented 3 years ago

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

万能的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 commented 2 years ago
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 commented 2 years ago

对不起,暂时不能亲自收到你的来信。当我看到了,我會尽快回复。

lyllovelemon commented 2 years ago

这是来自QQ邮箱的假期自动回复邮件。你好,我最近正在休假中,无法亲自回复你的邮件。我将在假期结束后,尽快给你回复。

seyeeL commented 1 year ago

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

emmachan613 commented 1 year ago

对不起,暂时不能亲自收到你的来信。当我看到了,我會尽快回复。

lyllovelemon commented 1 year ago

这是来自QQ邮箱的假期自动回复邮件。你好,我最近正在休假中,无法亲自回复你的邮件。我将在假期结束后,尽快给你回复。