Skip to content

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

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

Open
haizhilin2013 opened this issue Jul 19, 2019 · 5 comments
Labels
js JavaScript

Comments

@haizhilin2013
Copy link
Collaborator

第95天 分别写出数组的交集、并集、差集、补集这四个方法

@haizhilin2013 haizhilin2013 added the js JavaScript label Jul 19, 2019
@ghost
Copy link

ghost commented Jul 20, 2019

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
Copy link

/**
 *交集
 *
 * @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
Copy link

Konata9 commented Aug 20, 2019

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

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

// 交集
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
Copy link

样例

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
Copy link

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

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

No branches or pull requests

5 participants