I'm trying to write a function that looks through an array of objects (the first argument) and returns an array of all objects that contain all of the key/value pairs of a given object (the second argument).
我正在尝试编写一个查看对象数组(第一个参数)的函数,并返回包含给定对象(第二个参数)的所有键/值对的所有对象的数组。
My code below works only if the source
object (the second argument) contains one key/value pair. When the source
object has two or more key/value pairs, the result isn't as expected.
我的代码仅在源对象(第二个参数)包含一个键/值对时才有效。当源对象具有两个或更多键/值对时,结果不符合预期。
How to account for more than one key/value pair in the source
object?
如何在源对象中考虑多个键/值对?
function findObjects(collection, source) {
var result = [];
for (i=0; i<collection.length; i++) {
for (var prop in source) {
if (collection[i].hasOwnProperty(prop) && collection[i][prop] == source[prop]) {
console.log('Collection\'s object ' + [i] + ' contains the source\'s key:value pair ' + prop + ': ' + source[prop] + '!');
result.push(collection[i]);
} else {
console.log('fail');
}
}
}
console.log('The resulting array is: ' + result);
return result;
}
findObjects([{ "a": 1, "b": 2 }, { "a": 1 }, { "b": 2, "c": 2 }], { "a": 1, "b": 2 });
// only the first object should be returned since it contains both "a":1 and "b":2
3 个解决方案
#1
1
function findObjects(collection, source) {
var result = [];
for (i=0; i<collection.length; i++) {
var matches = true;
for (var prop in source) {
if (!collection[i].hasOwnProperty(prop) || collection[i][prop] !== source[prop]) {
matches = false;
break;
}
}
if (matches) {
result.push(collection[i]);
}
}
return result;
}
Basically, you have to check ALL properties and make sure they match, and then only then do you add it to your result
array.
基本上,您必须检查所有属性并确保它们匹配,然后才将它添加到结果数组中。
#2
2
You could use some array methods, like Array#map
您可以使用一些数组方法,如Array#map
The
map()
method creates a new array with the results of calling a provided function on every element in this array.map()方法创建一个新数组,其结果是在此数组中的每个元素上调用提供的函数。
and Array#every
和数组#every
The
every()
method tests whether all elements in the array pass the test implemented by the provided function.every()方法测试数组中的所有元素是否都通过了由提供的函数实现的测试。
and get the properties of source first with Object.keys
.
首先使用Object.keys获取源代码的属性。
The
Object.keys()
method returns an array of a given object's own enumerable properties, in the same order as that provided by afor...in
loop (the difference being that a for-in loop enumerates properties in the prototype chain as well).Object.keys()方法返回给定对象自己的可枚举属性的数组,其顺序与for ... in循环提供的顺序相同(不同之处在于for-in循环枚举原型链中的属性为好)。
function findObjects(collection, source) {
var keys = Object.keys(source); // get all properties of source
return collection.filter(function (c) { // filter collection
return keys.every(function (k) { // check every key
return c[k] === source[k]; // compare value of collection and source
});
});
}
console.log(findObjects([{ "a": 1, "b": 2 }, { "a": 1 }, { "b": 2, "c": 2 }], { "a": 1, "b": 2 }));
The same in ES6 syntax (read more: Arrow functions)
ES6语法相同(阅读更多:箭头功能)
Basically this style is a short writing of
基本上这种风格是简短的写作
function (x) { return y; }
became
成为
x => y
function findObjects(collection, source) {
const keys = Object.keys(source);
return collection.filter(c => keys.every(k => c[k] === source[k]));
}
console.log(findObjects([{ "a": 1, "b": 2 }, { "a": 1 }, { "b": 2, "c": 2 }], { "a": 1, "b": 2 }));
#3
1
The solution using Object.keys
, Array.forEach
and Array.some
functions:
使用Object.keys,Array.forEach和Array.some函数的解决方案:
function findObjects(arr, source) {
var keys = Object.keys(source), result = [];
arr.forEach(function(v){
!keys.some((k) => source[k] !== v[k]) && result.push(v);
});
return result;
}
console.log(findObjects([{ "a": 1, "b": 2 }, { "a": 1 }, { "b": 2, "c": 2 }], { "a": 1, "b": 2 }));
// it will output [{"a":1,"b":2}]
#1
1
function findObjects(collection, source) {
var result = [];
for (i=0; i<collection.length; i++) {
var matches = true;
for (var prop in source) {
if (!collection[i].hasOwnProperty(prop) || collection[i][prop] !== source[prop]) {
matches = false;
break;
}
}
if (matches) {
result.push(collection[i]);
}
}
return result;
}
Basically, you have to check ALL properties and make sure they match, and then only then do you add it to your result
array.
基本上,您必须检查所有属性并确保它们匹配,然后才将它添加到结果数组中。
#2
2
You could use some array methods, like Array#map
您可以使用一些数组方法,如Array#map
The
map()
method creates a new array with the results of calling a provided function on every element in this array.map()方法创建一个新数组,其结果是在此数组中的每个元素上调用提供的函数。
and Array#every
和数组#every
The
every()
method tests whether all elements in the array pass the test implemented by the provided function.every()方法测试数组中的所有元素是否都通过了由提供的函数实现的测试。
and get the properties of source first with Object.keys
.
首先使用Object.keys获取源代码的属性。
The
Object.keys()
method returns an array of a given object's own enumerable properties, in the same order as that provided by afor...in
loop (the difference being that a for-in loop enumerates properties in the prototype chain as well).Object.keys()方法返回给定对象自己的可枚举属性的数组,其顺序与for ... in循环提供的顺序相同(不同之处在于for-in循环枚举原型链中的属性为好)。
function findObjects(collection, source) {
var keys = Object.keys(source); // get all properties of source
return collection.filter(function (c) { // filter collection
return keys.every(function (k) { // check every key
return c[k] === source[k]; // compare value of collection and source
});
});
}
console.log(findObjects([{ "a": 1, "b": 2 }, { "a": 1 }, { "b": 2, "c": 2 }], { "a": 1, "b": 2 }));
The same in ES6 syntax (read more: Arrow functions)
ES6语法相同(阅读更多:箭头功能)
Basically this style is a short writing of
基本上这种风格是简短的写作
function (x) { return y; }
became
成为
x => y
function findObjects(collection, source) {
const keys = Object.keys(source);
return collection.filter(c => keys.every(k => c[k] === source[k]));
}
console.log(findObjects([{ "a": 1, "b": 2 }, { "a": 1 }, { "b": 2, "c": 2 }], { "a": 1, "b": 2 }));
#3
1
The solution using Object.keys
, Array.forEach
and Array.some
functions:
使用Object.keys,Array.forEach和Array.some函数的解决方案:
function findObjects(arr, source) {
var keys = Object.keys(source), result = [];
arr.forEach(function(v){
!keys.some((k) => source[k] !== v[k]) && result.push(v);
});
return result;
}
console.log(findObjects([{ "a": 1, "b": 2 }, { "a": 1 }, { "b": 2, "c": 2 }], { "a": 1, "b": 2 }));
// it will output [{"a":1,"b":2}]