[js] 分别写出数组的交集、并集、差集、补集这四个方法

haizhilin2013
2019-07-20 04:36:28 星期六
js
                    
                        
分别写出数组的交集、并集、差集、补集这四个方法
Comments per page
< Page 1 / 1 >
ghost 2019-07-20 01:20:13
const intersect = (a, b) => a.filter(i => b.includes(i)) // 交
const exclude = (a, b) => a.filter(i => !b.includes(i)) // 差
const union = (a, b) => exclude(a, b).concat(b) // 并
const unionAll = (a, b) => a.concat(b) // 重复并
const xor = (a, b) => exclude(a, b).concat(exclude(b, a)) // 补

这几个方法全是 O(n2) 的复杂度…性能很差

harmsworth 2019-08-09 11:47:44
/**
 *交集
 *
 * @param {*} arr1
 * @param {*} arr2
 */
function intersection (arr1, arr2) {
  return arr1.filter(v => arr2.includes(v))
}

/**
 *差集
 *
 * @param {*} arr1
 * @param {*} arr2
 */
function difference (arr1, arr2) {
  return arr1.filter(v => !arr2.includes(v))
}

/**
 *并集
 *
 * @param {*} arr1
 * @param {*} arr2
 */
function union (arr1, arr2) {
  return [...arr1, ...arr2]
}

/**
 *补集
 *
 * @param {*} arr1
 * @param {*} arr2
 */
function complement (arr1, arr2) {
  return difference(union(arr1, arr2), intersection(arr1, arr2))
}
Konata9 2019-08-20 10:47:43

概念有点忘了……找了张图

/**
 * 分别写出数组的交集、并集、差集、补集这四个方法
 */

// 交集
const getIntersection = (arr1, arr2) => {
  if (!Array.isArray(arr1) || !Array.isArray(arr2)) {
    return "Params must be array.";
  }

  // 将 arr1 与 arr2 每项都 stringify 化,可以进行对象的比较
  const arr1Formatted = arr1.map((item) => JSON.stringify(item));
  const arr2Formatted = arr2.map((item) => JSON.stringify(item));

  return arr1Formatted
    .filter((item) => arr2Formatted.includes(item))
    .map((item) => JSON.parse(item));
};

// 并集
const getUnion = (arr1, arr2) => {
  if (!Array.isArray(arr1) || !Array.isArray(arr2)) {
    return "Params must be array.";
  }

  // 将 arr1 与 arr2 每项都 stringify 化,可以进行对象的比较
  const arr1Formatted = arr1.map((item) => JSON.stringify(item));
  const arr2Formatted = arr2.map((item) => JSON.stringify(item));
  return arr1Formatted
    .filter((item) => !arr2Formatted.includes(item))
    .concat(arr2Formatted)
    .map((item) => JSON.parse(item));
};

// 差集
const getDiff = (arr1, arr2) => {
  if (!Array.isArray(arr1) || !Array.isArray(arr2)) {
    return "Params must be array.";
  }

  // 将 arr1 与 arr2 每项都 stringify 化,可以进行对象的比较
  const arr1Formatted = arr1.map((item) => JSON.stringify(item));
  const arr2Formatted = arr2.map((item) => JSON.stringify(item));

  return arr1Formatted
    .filter((item) => !arr2Formatted.includes(item))
    .map((item) => JSON.parse(item));
};

// 补集
const getComplement = (arr1, arr2) => {
  if (!Array.isArray(arr1) || !Array.isArray(arr2)) {
    return "Params must be array.";
  }

  return getUnion(getDiff(arr1, arr2), getDiff(arr2, arr1));
};

const arr1 = [1, 2, 3, 4, 5, 6];
const arr2 = ["a", "b", 3, 4, 6, 7, 8];
getIntersection(arr1, arr2);
getUnion(arr1, arr2);
getDiff(arr1, arr2);
getComplement(arr1, arr2);

const brr1 = [1, {a: 1, b: 2}, 3, 4, [2, 3, 3], 6];
const brr2 = [{a: 1}, {a: 1, b: 2}, 3, 4, 6, [2, 3, 3], 8];
getIntersection(brr1, brr2);
getUnion(brr1, brr2);
getDiff(brr1, brr2);
getComplement(brr1, brr2);
ZindexYG 2019-12-26 01:59:36

样例

var a = [1,2,3,4,5]
var b = [2,4,6,8,10]

1,使用 filter、concat 来计算

//交集
var c = a.filter(function(v){ return b.indexOf(v) > -1 })
//差集
var d = a.filter(function(v){ return b.indexOf(v) == -1 })
//补集
var e = a.filter(function(v){ return !(b.indexOf(v) > -1) })
        .concat(b.filter(function(v){ return !(a.indexOf(v) > -1)}))
//并集
var f = a.concat(b.filter(function(v){ return !(a.indexOf(v) > -1)}))

2,对 Array 进行扩展

//数组功能扩展
//数组迭代函数
Array.prototype.each = function(fn){
  fn = fn || Function.K;
   var a = [];
   var args = Array.prototype.slice.call(arguments, 1);
   for(var i = 0; i < this.length; i++){
       var res = fn.apply(this,[this[i],i].concat(args));
       if(res != null) a.push(res);
   }
   return a;
};

//数组是否包含指定元素
Array.prototype.contains = function(suArr){
  for(var i = 0; i < this.length; i ++){
      if(this[i] == suArr){
          return true;
      }
   }
   return false;
}

//不重复元素构成的数组
Array.prototype.uniquelize = function(){
   var ra = new Array();
   for(var i = 0; i < this.length; i ++){
      if(!ra.contains(this[i])){
          ra.push(this[i]);
      }
   }
   return ra;
};

//两个数组的交集
Array.intersect = function(a, b){
   return a.uniquelize().each(function(o){return b.contains(o) ? o : null});
};

//两个数组的差集
Array.minus = function(a, b){
   return a.uniquelize().each(function(o){return b.contains(o) ? null : o});
};

//两个数组的补集
Array.complement = function(a, b){
   return Array.minus(Array.union(a, b),Array.intersect(a, b));
};

//两个数组并集
Array.union = function(a, b){
   return a.concat(b).uniquelize();
};

/*使用*/
console.log("a与b的交集:", Array.intersect(a, b));
console.log("a与b的差集:", Array.minus(a, b));
console.log("a与b的补集:", Array.complement(a, b));
console.log("a与b的并集:", Array.union(a, b));

3,ES6

var sa = new Set(a);
var sb = new Set(b);
// 交集
let intersect = a.filter(x => sb.has(x));
// 差集
let minus = a.filter(x => !sb.has(x));
// 补集
let complement  = [...a.filter(x => !sb.has(x)), ...b.filter(x => !sa.has(x))];
// 并集
let unionSet = Array.from(new Set([...a, ...b]));
xiaoqiangz 2022-06-23 09:53:41

let a = [1,2,3,4,5,6], b = [1,2,8,9,10]
// 交集
function intersection(a ,b) {
return a.filter(item => b.includes(item))
}
console.log(intersection(a, b))
// 并集
function union(a, b) {
let arr = b.filter(item => !a.includes(item))
return [...a, ...arr]
}
console.log(union(a, b))
// 差集 比如arrA有,而arrB没有
function difference(a,b) {
return [...a.filter(item => !b.includes(item))]
}
console.log(difference(a, b))
// 补集 两个数组各自没有的集合
function complement(a, b) {
return [...a.filter(item => !b.includes(item)), ...b.filter(item => !a.includes(item))]
}
console.log(complement(a, b))

学习不打烊,充电加油只为遇到更好的自己,365天无节假日,每天早上5点纯手工发布前端知识点(死磕自己,愉悦大家)。希望大家在这浮夸的前端圈里,保持冷静,坚持每天花20分钟来学习与思考。在这千变万化,类库层出不穷的前端,建议大家不要等到找工作时,才狂刷题,提倡每日学习!欢迎大家关注3+1开源项目!希望大家每人去学习与思考!(不要为了谁而来,要为自己而努力!

【关注官方公众号】 每天4:30-5:00推送
【公众号推荐】 一起折腾前端算法
【微信学习群】 备注3+1