一、JS数组求并集,交集和差集

需求场景

最近,自己项目中有一些数组操作,涉及到一些数学集的运算,趁着完成后总结一下。

简化问题之后,现有两数组a = [1, 2, 3]b = [2, 4, 5],求a,b数组的并集,交集和差集。

方法选择

JS在ES6,ES7之后,新增了一些数组方法,如果能够使用,那是极好的,毕竟自己写封装函数还是比较辛苦的。

ES7

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

var boolean = array.includes(searchElement[, fromIndex])

  • // 并集
  • 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]
js

ES6

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

Array.from(arrayLike[, mapFn[, thisArg]])

  • 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]
js

ES5

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

  • 不考虑NaN(数组中不含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]
js
  • 考虑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]
js

结语

由于JS语言的特殊性,NaN在数组的数学集操作中有不少问题,好在ES6和ES7中,新的数组方法解决了部分情况。单从简洁性来看,ES7的方法最简洁明了。

就是不知道新的标准要猴年马月才能被各大浏览器兼容,目前还是使用Babel比较靠谱。

本文链接:https://excaliburhan.com/post/js-set-operation.html

二、js求对象数组的交集/并集/差集/去重

      1.求交集
    var arr1 = [{name:'name1',id:1},{name:'name2',id:2},{name:'name3',id:3}];
var arr1Id = [1,2,3]
var arr2 = [{name:'name1',id:1},{name:'name2',id:2},{name:'name3',id:3},{name:'name4',id:4},{name:'name5',id:5}];
var result = arr2.filter(function(v){
return arr1Id.indexOf(v.id)!==-1 // 利用filter方法来遍历是否有相同的元素
})
console.log(result);
      2.求并集
    let arr1 = [{name:'name1',id:1},{name:'name2',id:2},{name:'name3',id:3}];
let arr2 = [{name:'name1',id:1},{name:'name4',id:4},{name:'name5',id:5}];
let arr3 = arr1.concat(arr2);
let result = [];
var obj = [];
result = arr3.reduce(function(prev, cur, index, arr) {
console.log(prev, cur);
obj[cur.id] ? '' : obj[cur.id] = true && prev.push(cur);
return prev;
}, []);
console.log(result);
1
2
3
4
5
6
7
8
9
3.求差集<br>    let arr1 = [{name:'name1',id:1},{name:'name2',id:2},{name:'name3',id:3}];
  let arr1Id = [1,2,3];
  let arr2 = [{name:'name1',id:1},{name:'name4',id:4},{name:'name5',id:5}];
  let arr2Id = [1,4,5];
  let arr3 = arr1.concat(arr2);
  let result = arr3.filter(function(v){
      return arr1Id.indexOf(v.id)===-1 || (arr2Id.indexOf(v.id)===-1)
  })
  console.log(result);

  

      4.去重
    let arr = [{name:'name1',id:1},{name:'name2',id:2},{name:'name3',id:3},{name:'name1',id:1},{name:'name4',id:4},{name:'name5',id:5}];
var obj = [];
let result = arr.reduce(function(prev, cur, index, arr) {
console.log(prev, cur);
obj[cur.id] ? '' : obj[cur.id] = true && prev.push(cur);
return prev;
}, []);

实际组件中应用去重

 a方法
       let includeThis = false
let vm = this
if(vm.informedPersonList.length>0){
vm.informedPersonList.forEach(el =>{
if(el.id == vm.selectedTrueItem.id){
includeThis = true
}
})
}
if(includeThis===false){
vm.informedPersonList.push(vm.selectedTrueItem)
}else{
Message({message: '请勿重复添加',type: 'warning'})
}
 b方法(必须先let informedPersonL = vm.informedPersonList,不能直接使用vm.informedPersonList,否则浏览器控制台会报错)
1
2
3
4
5
6
7
8
9
vm.informedPersonList.push(this.selectedTrueItem)
let obj = {};
let informedPersonL = vm.informedPersonList
informedPersonL = informedPersonL.reduce((cur,next) => {
    obj[next.id] ? "" : obj[next.id] = true && cur.push(next);
    return cur;
},[]) //设置cur默认类型为数组,并且初始值为空的数组
vm.selectedTrueItem = {}
vm.$emit("backInformedPList",informedPersonL);

  

 来源:https://www.cnblogs.com/cx709452428/p/10180807.html
以为两个数组都是对象数组怎么办?
先获取某个数组根据某属性去重后的值classArr。 然后在
 let arr1ID= arrayObjectDistinctReturnKey(arr, "id");
然后
 var arr2 = [{name:'name1',id:1},{name:'name2',id:2},{name:'name3',id:3},{name:'name4',id:4},{name:'name5',id:5}];
var result = arr2.filter(function(v){
return arr1Id.indexOf(v.id)!==-1 // 利用filter方法来遍历是否有相同的元素
})
//去重方法
 function arrayObjectDistinctReturnKey(arr, key) {
// console.log('arr', arr)
var result = []
var obj = {}
for (var i = 0; i < arr.length; i++) {
if (arr[i][key]) {
if (!obj[arr[i][key]]) {
result.push(arr[i][key])
obj[arr[i][key]] = true
}
}
}
// console.log('result', result)
return result
}

 js去重相关文章: https://www.cnblogs.com/hao-1234-1234/p/11122383.html

 

JS 对象 数组求并集,交集和差集的更多相关文章

  1. 【Sets】使用Google Guava工程中Sets工具包,实现集合的并集/交集/补集/差集

    获取两个txt文档的内容~存储进集合中求集合的并集/交集/补集/差集 package com.sxd.readLines.aboutDB; import java.io.BufferedReader; ...

  2. 前台的js对象数组传到后台处理。在前台把js对象数组转化为json字符串,在后台把json字符串解析为List<>

    前台的js对象数组传到后台处理.在前台把js对象数组转化为json字符串,在后台把json字符串解析为List<>

  3. js对象数组中的某属性值 拼接成字符串

    js对象数组中的某属性值 拼接成字符串 var objs=[ {id:1,name:'张三'}, {id:2,name:'李四'}, {id:3,name:'王五'}, {id:4,name:'赵六' ...

  4. JS对象—数组总结(创建、属性、方法)

    JS对象—数组总结(创建.属性.方法) 1.创建字符串 1.1 new Array() var arr1 = new Array(); var arr2 = new Array(6); 数组的长度为6 ...

  5. js对象数组多字段排序

    来源:js对象数组按照多个字段进行排序 一.数组排序 Array.sort()方法可以传入一个函数作为参数,然后依据该函数的逻辑,进行数组的排序. 一般用法:(数组元素从小大进行排序) var a = ...

  6. js对象/数组深度复制

    今天碰到个问题,js对象.数组深度复制:之前有见过类似的,不过没有实现函数复制,今晚想了一下,实现代码如下: function clone(obj) { var a; if(obj instanceo ...

  7. js对象,数组,字符串的操作

    循环绑定=>变量污染 for (var i = 0;i<lis.length;i++){ lis[i].index = i;#给页面元素对象添加一个任意属性(保留索引的属性index) # ...

  8. js对象数组深度去重和深度排序

    使用collect.js处理数组和对象 https://github.com/ecrmnn/collect.js/# 引入collect.js https://github.com/ecrmnn/co ...

  9. html标签内部简单加js 一维数组求最大值 最小值两个值位置和数字金字塔图形

     html标签内部,简单加js <a href=""></a><!DOCTYPE html PUBLIC "-//W3C//DTD XHTM ...

随机推荐

  1. javafx这些学会后,开发就不难了,往tablecloumn列中添加按钮,修改javafx中tableview中tablecell中的值,修改完回车表示保存到内存中

    javafx开发过程中遇见难题,往tablecloumn列中添加按钮 想了很久的方法,也配有办法判断每行中有数据的地方添加按钮set bank_caozuo.setCellFactory((col)- ...

  2. LwIP应用开发笔记之五:LwIP无操作系统TCP服务器

    前面我们实现了UDP服务器及客户端以及基于其上的TFTP应用服务器.接下来我们将实现同样广泛应用的TCP协议各类应用. 1.TCP简述 TCP(Transmission Control Protoco ...

  3. npx vs npm

    npx vs npm npx 使用教程

  4. [数据结构 - 第3章] 线性表之单链表(C++实现)

    一.类定义 单链表类的定义如下: #ifndef SIGNALLIST_H #define SIGNALLIST_H typedef int ElemType; /* "ElemType类型 ...

  5. spark 性能优化简要总结

    1.从同一个数据源尽量只创建一个rdd,后续业务逻辑复用该rdd2.如果要对某个rdd进行多次的transformation或action操作,应当持久化该rdd3.从数据源读取到rdd后,要尽早的进 ...

  6. PHP 跨域资源共享 CORS 设定

    CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing). 它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从 ...

  7. 22 Oracle数据库基础入门

    1.Oracle数据库的介绍 ORACLE 数据库系统是美国ORACLE 公司(甲骨文)提供的以分布式数据库为核心的一组软件产品,是目前最流行的客户/服务器(CLIENT/SERVER)或 B/S 体 ...

  8. Kubernetes集群中Jmeter对公司演示的压力测试

    6分钟阅读 背景 压力测试是评估Web应用程序性能的有效方法.此外,越来越多的Web应用程序被分解为几个微服务,每个微服务的性能可能会有所不同,因为有些是计算密集型的,而有些是IO密集型的. 基于微服 ...

  9. Java多线程编程(4)--线程同步机制

    一.锁 1.锁的概念   线程安全问题的产生是因为多个线程并发访问共享数据造成的,如果能将多个线程对共享数据的并发访问改为串行访问,即一个共享数据同一时刻只能被一个线程访问,就可以避免线程安全问题.锁 ...

  10. Vue框架(四)——路由跳转、路由传参、cookies、axios、跨域问题、element-ui模块

    路由跳转 三种方式: $router.push / $router.go / router-link to this.$router.push('/course'); this.$router.pus ...