返回仅存在于香草 JS 中的两个对象数组中的值?

Returning values that only exist in two arrays of objects in vanilla JS?

我有两个包含一组相似项目的对象数组

arr1 = [ 
    {property1: 'foo', property2: 'bar', property3: 'baz'},
    {property1: 'moo', property2: 'bar', property3: 'maz'}
]

arr2 = [
    {property2: 'bar', property3: 'maz'},
    {property2: 'bar', property3: 'santa'}
]

我需要编写一个将两个对象数组作为参数的函数。此函数需要 return 每个对象的 property1 匹配数组二中的其余键。

所以,我的函数应该采用上面的两个数组和 return 仅 'moo'。我已经在这几个小时了,似乎无法正确解决问题。

注意事项:我想在不求助于库的情况下了解解决方案,我想使用函数式方法解决它,没有 vars 或 for 循环。希望改用 reduce() map() 和 filter()。

我已将 property1property2property3 分别缩短为 p1p2p3

你没有给出键在对象之间变化的迹象,所以这个解决方案假设:

  • p1p2p3 将始终存在于 arr1 个对象中
  • p2p3 将始终存在于 arr2 个对象中。

var arr1 = [
  {p1: 'foo', p2: 'bar', p3: 'baz'},
  {p1: 'moo', p2: 'bar', p3: 'maz'},
  {p1: 'zoo', p2: 'bar', p3: 'maz'} // added to show multiple outputs
];

var arr2 = [
  {p2: 'bar', p3: 'maz'},
  {p2: 'bar', p3: 'santa'}
];

const match = xs => ({p1, p2, p3}) =>
  xs.some(({p2:y, p3:z}) => p2 === y && p3 === z);

const prop = x => y => y[x];

var out = arr1.filter(match(arr2)).map(prop('p1'));

console.log(out);

有些人会批评 filter->map 多次不必要地遍历数组。您可以将过滤和映射组合在一个 reduce 中,但我认为可读性会受到一点影响...

var arr1 = [
  {p1: 'foo', p2: 'bar', p3: 'baz'},
  {p1: 'moo', p2: 'bar', p3: 'maz'},
  {p1: 'zoo', p2: 'bar', p3: 'maz'} // added to show multiple outputs
];

var arr2 = [
  {p2: 'bar', p3: 'maz'},
  {p2: 'bar', p3: 'santa'}
];

const match = xs => ({p1, p2, p3}) =>
  xs.some(({p2:y, p3:z}) => p2 === y && p3 === z);

var out = arr1.reduce((acc, x) => {
  if (match (arr2) (x))
    return [...acc, x.p1]
  else
    return acc
}, []);

console.log(out);

Mix/match让您满意的解决方案。

我可能会根据arr1;

做如下操作

function check(a1,a2){
  return a1.map(o => a2.reduce((p,q) =>  Object.values(o).every(v => Object.values(Object.assign({},o,q)).includes(v)) || p,false));
}

var arr1 = [ 
    {property1: 'foo', property2: 'bar', property3: 'baz'},
    {property1: 'moo', property2: 'bar', property3: 'maz'}
],

    arr2 = [
    {property2: 'bar', property3: 'maz'},
    {property2: 'bar', property3: 'santa'}
];

result = check(arr1,arr2);
console.log(result);

Chrome v54 或 FF v50 似乎是 Object.values() 运行所必需的。

filter() 嵌套 some() 而没有 for 循环的函数式方法:

var arr1 = [
  {p1: 'foo', p2: 'bar', p3: 'baz'},
  {p1: 'moo', p2: 'bar', p3: 'maz'},
  {p1: 'zoo', p2: 'bar', p3: 'maz'} // added to show multiple outputs
];
var arr2 = [
  {p2: 'bar', p3: 'maz'},
  {p2: 'bar', p3: 'santa'}
];
var result = arr1.filter(x => arr2.some(y => y.p2 === x.p2 && y.p3 === x.p3)).map(x => x.p1);
console.log(result); // [ 'moo', 'zoo' ]