JS数组求并集交集和差集 (ES7/ES6/ES5)

集合的分类:

  • 并集:以属于A或属于B的元素为元素的集合成为A与B的并(集)记作A∪B(或B∪A),读作“A并B”(或“B并A”),即A∪B={x|x∈A,或x∈B}
  • 交集:以属于A且属于B的元素为元素的集合成为A与B的交(集)记作A∩B(或B∩A),读作“A交B”(或“B交A”),即A∩B={x|x∈A,且x∈B}
  • 差集:以属于A而不属于B的元素为元素的集合成为A与B的差(集)记作A-B(或B∩A),读作“A减B”,即A-B={x∣x∈A,且x∉B}

方法一:

ES7新增了一个Array.prototype.includes的数组方法,用于返回一个数组是否包含指定元素,结合filter方法

// 并集
let union = a.concat(b.filter(v => !a.includes(v))) // [1,2,3,4,5]
// 交集
let intersection = a.filter(v => b.includes(v)) // [2]
// 差集
let difference = a.concat(b).filter(v => !a.includes(v) || !b.includes(v)) // [1,3,4,5]

方法二:

ES6中新增的一个Array.from方法,用于将类数组对象和可遍历对象转化为数组。只要类数组有length长度,基本都可以转化为数组。结合Set结构实现数学集求解。

let aSet = new Set(a)
let bSet = new Set(b)
// 并集
let union = Array.from(new Set(a.concat(b))) // [1,2,3,4,5]
// 交集
let intersection = Array.from(new Set(a.filter(v => bSet.has(v)))) // [2]
// 差集
let difference = Array.from(new Set(a.concat(b).filter(v => !aSet.has(v) || !bSet.has(v)))) // [1,3,4,5]

方法三:

ES5可以利用filterindexOf进行数学集操作,但是,由于indexOf方法中NaN永远返回-1,所以需要进行兼容处理。

不考虑NaN

// 并集
var union = a.concat(b.filter(function(v) {
return a.indexOf(v) === -1})) // [1,2,3,4,5]
// 交集
var intersection = a.filter(function(v){ return b.indexOf(v) > -1 }) // [2]
// 差集
var difference = a.filter(function(v){ return b.indexOf(v) === -1 }).concat(b.filter(function(v){ return a.indexOf(v) === -1 })) // [1,3,4,5]

考虑NaN

var aHasNaN = a.some(function(v){ return isNaN(v) })
var bHasNaN = b.some(function(v){ return isNaN(v) })
// 并集
var union = a.concat(b.filter(function(v) {
return a.indexOf(v) === -1 && !isNaN(v)})).concat(!aHasNaN & bHasNaN ? [NaN] : []) // [1,2,3,4,5]
// 交集
var intersection = a.filter(function(v){ return b.indexOf(v) > -1 }).concat(aHasNaN & bHasNaN ? [NaN] : []) // [2]
// 差集
var difference = a.filter(function(v){ return b.indexOf(v) === -1 && !isNaN(v) }).concat(b.filter(function(v){ return a.indexOf(v) === -1 && !isNaN(v) })).concat(aHasNaN ^ bHasNaN ? [NaN] : []) // [1,3,4,5]

添加新评论