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
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
Share
Improve this question
edited Jun 15, 2016 at 20:35
Travis J
82.4k42 gold badges211 silver badges279 bronze badges
asked Jun 15, 2016 at 20:33
Brian ZelipBrian Zelip
3,2217 gold badges38 silver badges50 bronze badges
0
3 Answers
Reset to default 3You could use some array methods, like Array#map
The
map()
method creates a new array with the results of calling a provided function on every element in this array.
and Array#every
The
every()
method tests whether all elements in the array pass the test implemented by the provided function.
and get the properties of source first with 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).
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]; // pare 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)
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 }));
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.
The solution using Object.keys
, Array.forEach
and Array.some
functions:
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}]