如何在JavaScript React中找到两个对象数组之间的所有交集?

6

我有两个对象数组。这些数组可以是任意长度。例如,我的第一个数组 "details" 包含三个对象。

let details = [
{a: 1, b: 200, name: "dad"}, 
{a:2, b: 250, name: "cat"}, 
{a:3, b: 212, name: "dog" } 
] 

第二个数组由四个对象组成:

let certs = [
{id: 991, b: 250, dn: "qwerty", sign: "GOST"}, 
{id: 950, b: 251, dn: "how", sign: "RSA" }, 
{id: 100, b: 250, dn: "how are", sign: "twofish" }, 
{id: 957, b: 212, dn: "how you", sign: "black" }
] 

如何获取由对象某个属性的所有交集组成的数组,例如由'b'?
我的意思是从“certs”数组中获取过滤后的数组,该数组仅包含三个对象而不是四个。
因为在certs数组中索引为1的元素具有属性“b”,其等于251。但是“details”数组中没有具有属性b等于251的对象。
因此,我的过滤后的certs数组应该只包含三个对象。如何实现?
我尝试了lodash方法,但它们都不适用。例如:
_.intersectionBy(certs, details, 'b')

只给了我这个:

0: {id: 991, b: 250, dn: "qwerty", sign: "GOST"}
1: {id: 957, b: 212, dn: "how you", sign: "black"}
length: 2

这个对象在最终数组中不存在:

{id: 100, b: 250, dn: "how are", sign: "twofish" }
4个回答

2
只需两次使用 filter() 方法:

let details = [
  {a: 1, b: 200, name: "dad"}, 
  {a:2, b: 250, name: "cat"}, 
  {a:3, b: 212, name: "dog" } 
] 

let certs = [
  {id: 991, b: 250, dn: "qwerty", sign: "GOST"}, 
  {id: 950, b: 251, dn: "how", sign: "RSA" }, 
  {id: 100, b: 250, dn: "how are", sign: "twofish" }, 
  {id: 957, b: 212, dn: "how you", sign: "black" }
] 

const result = certs.filter(cert => {
 let arr = details.filter(detail => detail.b === cert.b)
 return !(arr.length === 0)
});

console.log(result)


0
你可以定义一个函数,接受一个表达式并对其进行评估,以便根据你的需要进行过滤。
下面的示例使用 filter 对你自己的 expression 进行过滤。

let details = [
  {a: 1, b: 200, name: "dad"}, 
  {a:2, b: 250, name: "cat"}, 
  {a:3, b: 212, name: "dog" } 
];
let certs = [
  {id: 991, b: 250, dn: "qwerty", sign: "GOST"}, 
  {id: 950, b: 251, dn: "how", sign: "RSA" }, 
  {id: 100, b: 250, dn: "how are", sign: "twofish" }, 
  {id: 957, b: 212, dn: "how you", sign: "black" }
];

const intersectByExpression = (a, b, expression) => {
  return [...a,...b].filter(i => expression(i)); // <-- evaluates the expression.
  //     ^---------^-- concat items and filters.
}

// All elements where `b` exists and is exactly 250.
console.log(
  intersectByExpression(details, certs, o => o.b === 250)
  //                                    ^--------------^-- Expression to evaluate.
);

// Other samples.
// All elements where id is lower or equals 100.
console.log(
  intersectByExpression(details, certs, o => o.id <= 100)
);

// All elements where id is greater than 950 and b is greater or equals 250.
console.log(
  intersectByExpression(details, certs, o => o.id >= 950 && o.b >= 250)
);


0

有一个方便的库叫做lodash,它有一个名为intersectionBy的函数非常适合解决这个问题。

let details = [
{a: 1, b: 200, name: "dad"}, 
{a:2, b: 250, name: "cat"}, 
{a:3, b: 212, name: "dog" } 
] 
let certs = [
{id: 991, b: 250, dn: "qwerty", sign: "GOST"}, 
{id: 950, b: 251, dn: "how", sign: "RSA" }, 
{id: 100, b: 250, dn: "how are", sign: "twofish" }, 
{id: 957, b: 212, dn: "how you", sign: "black" }
] 
 _.intersectionBy(certs, details, 'b')

不行,lodash 不适用。我已经尝试过 lodash。如果我使用这个:_.intersectionBy(certs, details, 'b'),那么我只会得到一个仅包含两个对象的数组。它不包括具有重复 b 值的对象,只有唯一的对象。 - Dragon14

0
let details = [
{a: 1, b: 200, name: "dad"}, 
{a:2, b: 250, name: "cat"}, 
{a:3, b: 212, name: "dog" } 
];

let certs = [
{id: 991, b: 250, dn: "qwerty", sign: "GOST"}, 
{id: 950, b: 251, dn: "how", sign: "RSA" }, 
{id: 100, b: 250, dn: "how are", sign: "twofish" }, 
{id: 957, b: 212, dn: "how you", sign: "black" }
]

const result = certs.filter(cert => details.find(detail => detail.b === cert.b));

console.log(result);

如果您能提供更多的例子来解释您的问题,那就太好了,:)


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