在多个数组中查找交集

6
我试图查找多个数组内的交集值,这些数组嵌套在一个对象中,示例如下:
object = {
  filterA: ["1","2","3","4"],
  filterB: ["2","5","6","7"],
  filterN: ["2","4","7"]
}

该对象可以包含多个数组,键名可能会变化。在所描述的对象中,我只需要返回“2”。
我尝试在此答案的基础上进行修改:Multiple array intersection in javascript 但是我无法理解它,因为它使用了静态变量(a、b、c)作为示例。如果有一种使用lodash的方法,将不胜感激,但ES5中的原生JavaScript也可以实现!

7个回答

9

您可以获取这些值并使用 Set 进行过滤,然后使用 Set#has

var object = { filterA: ["1", "2", "3", "4"], filterB: ["2", "5", "6", "7"], filterN: ["2", "4", "7"] },
    result = Object
        .values(object)
        .reduce((a, b) => b.filter(Set.prototype.has, new Set(a)));

console.log(result);


很好地使用了过滤器的 this - Ori Drori
在检查了lodash解决方案的值之后,我最终使用了这个解决方案。一开始它还可以,但是一段时间后出现了某些原因导致错误值的问题。因为我使用的系统不支持es6转换,所以我使用了在线babel (https://babeljs.io/repl)转换答案。 - Presian Nedyalkov

2
我有一个简单的一行代码解决方案:
const res = Object.values(object).reduce((a, b) => a.filter(i => b.includes(i)))

但是,由于您想要ES5(ECMAScript 2009)版本,这意味着不能使用箭头函数,不能使用includes(),也不能使用Set对象。

const res = Object.values(object).reduce(function (a, b) { 
  return a.filter(function(i) {
    //return b.includes(i);
    return b.indexOf(i) >= 0;
  });
});

console.log(res);

嗨@wentjun,你能给我一个ES5的解决方案吗(不要用箭头函数)? - Presian Nedyalkov
“includes” 在 ES5 环境中可能没有 polyfill 的情况下不可用。 - charlietfl
好的!谢谢@charlietfl,我已经用indexOf() >= 0替换了includes来检查数组中是否存在该元素。 - wentjun
@PresianNedyalkov 好的,我又编辑了一次。 - wentjun

1

reduce 能为你完成工作。请查看下面的代码。

var object = {
  filterA: ["1","2","3","4"],
  filterB: ["2","5","6","7"],
  filterN: ["2","4","7"]
}

var res = Object.values(object).reduce(function (acc, array) {
  return _.intersection(acc, array)
})

console.log(res)
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.11/lodash.min.js"></script>


1

遍历第一个属性值(数组),并通过与剩余属性值进行比较来进行过滤。

// get property values(arraya as array)
let arr = Object.values(object);


let res = arr[0]
  // iterate over first array
  // check value present in remaining object values(arrays)
  .filter(v => arr.slice(1).every(a => a.includes(v)));

let object = {
  filterA: ["1", "2", "3", "4"],
  filterB: ["2", "5", "6", "7"],
  filterN: ["2", "4", "7"]
};


let arr = Object.values(object);

let res = arr[0].filter(v => arr.slice(1).every(a => a.includes(v)));


console.log(res)


嗨@Pranav,你能给我一个ES5版本吗,不要用箭头函数。 - Presian Nedyalkov
@PresianNedyalkov:当然。 - Pranav C Balan
@PresianNedyalkov arr[0] .filter(function(v){ return arr.slice(1).every(function(a){ return a.includes(v)}) }); - Pranav C Balan

0
Lodash的_.intersection()可以处理多个数组。您可以使用_.flow()创建一个函数,该函数从对象中使用_.values()获取数组的数组,并使用_.spread()_.intersection()计算交集。

const { flow, values, spread, intersection } = _

const fn = flow(
  values, // get the arrays
  spread(_.intersection) // spread into intersection
)

const object = {
  filterA: ["1","2","3","4"],
  filterB: ["2","5","6","7"],
  filterN: ["2","4","7"]
}

const result = fn(object)

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>


0
object = {
  filterA: ["1","2","3","4"],
  filterB: ["2","5","6","7"],
  filterN: ["2","4","7"]
}

let arr = Object.values(object);

let res = arr[0].filter(v => arr.slice(1).every(a => a.includes(v)));


console.log(res)

嗨@umer,你能给我一个ES5的解决方案(不能使用箭头函数)吗? - Presian Nedyalkov
尝试这个:arr[0].filter(function(v){ return arr.slice(1).every(function(a){ return a.includes(v)}) }); - Umer Arif

0
let arrayOfComparisonArrays = [[1,2,3,4,5], [5,3], [1,3,4,5], [5,1,3]]
let intersectionArray

intersectionArray = arrayOfComparisonArrays.reduce((lastArray, nextArray)=>{
    let intersection = lastArray.filter(x => nextArray.includes(x))
    return intersection
})

//intersectionArray: [ 3, 5 ] 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接