Currently I am working on an JavaScript exercise.
The aim of the exercise is to compare the array which formed with different objects. there are 2 parameters for the function: The collection is the main array, and the source is the comparison criteria. Only the objects in main array which contains the key and same properties as source array would be returned.
The outcome should be as follows:
whatIsInAName(
[{ first: "Romeo", last: "Montague" }, { first: "Mercutio", last: null }, { first: "Tybalt", last: "Capulet" }],
{ last: "Capulet" }
) // should return [{ first: "Tybalt", last: "Capulet" }].
whatIsInAName(
[{ "apple": 1 }, { "apple": 1 }, { "apple": 1, "bat": 2 }],
{ "apple": 1 }
) // should return [{ "apple": 1 }, { "apple": 1 }, { "apple": 1, "bat": 2 }]
whatIsInAName(
[{ "apple": 1, "bat": 2 }, { "bat": 2 }, { "apple": 1, "bat": 2, "cookie": 2 }],
{ "apple": 1, "bat": 2 }
) // should return [{ "apple": 1, "bat": 2 }, { "apple": 1, "bat": 2, "cookie": 2 }]
whatIsInAName(
[{ "apple": 1, "bat": 2 }, { "apple": 1 }, { "apple": 1, "bat": 2, "cookie": 2 }],
{ "apple": 1, "cookie": 2 }
) // should return [{ "apple": 1, "bat": 2, "cookie": 2 }]
whatIsInAName(
[{ "apple": 1, "bat": 2 }, { "apple": 1 }, { "apple": 1, "bat": 2, "cookie": 2 }, { "bat":2 }],
{ "apple": 1, "bat": 2 }
) // should return [{ "apple": 1, "bat": 2 }, { "apple": 1, "bat": 2, "cookie":2 }]
whatIsInAName(
[{"a": 1, "b": 2, "c": 3}],
{"a": 1, "b": 9999, "c": 3}
) // should return []
To tackle this, I use the array filter function and aim to select the object which matches the criteria and return as new array. The code is as follows:
function whatIsInAName(collection, source) {
var arr = [];
var key = Object.keys(source)
return collection.filter(function(x){
for(var y = 0; y < key.length; y++){
if(x.hasOwnProperty(key[y]) && x[key[y]] == source[key[y]]){
return true;
}
}
return true;
})
}
whatIsInAName([{ first: "Romeo", last: "Montague" }, { first: "Mercutio", last: null }, { first: "Tybalt", last: "Capulet" }], { last: "Capulet" });
However, when I test the condition in the console, it returns the following:
[{…}, {…}, {…}]
And at the same time, I saw that there is an similar answer. But the difference is, it use the negative selections which return false when there is sth not matched like this:
function whatIsInAName(collection, source) {
var srcKeys = Object.keys(source);
return collection.filter(function (obj) {
for(var i = 0; i < srcKeys.length; i++) {
if(!obj.hasOwnProperty(srcKeys[i]) || obj[srcKeys[i]] !== source[srcKeys[i]]) {
return false;
}
}
return true;
});
}
// test here
whatIsInAName([{ first: "Romeo", last: "Montague" }, { first: "Mercutio", last: null }, { first: "Tybalt", last: "Capulet" }], { last: "Capulet" });
This time it works.
So what I want to know is, what is my error on the first script? And if I still want to use the positive criteria i.e only return cases which match the both criteria, how can I make it? Many thanks