返回仅存在于香草 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()。
我已将 property1
、property2
和 property3
分别缩短为 p1
、p2
和 p3
。
你没有给出键在对象之间变化的迹象,所以这个解决方案假设:
p1
、p2
和 p3
将始终存在于 arr1
个对象中
p2
和 p3
将始终存在于 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' ]
我有两个包含一组相似项目的对象数组
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()。
我已将 property1
、property2
和 property3
分别缩短为 p1
、p2
和 p3
。
你没有给出键在对象之间变化的迹象,所以这个解决方案假设:
p1
、p2
和p3
将始终存在于arr1
个对象中p2
和p3
将始终存在于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' ]