How to match objects with the same key-value pairs passed as arguments?

This is a FreeCodeCamp task named Wherefore art thou.

I have to Make a function that looks through an array of objects (first argument) and returns an array of all objects that have matching name and value pairs (second argument). Each name and value pair of the source object has to be present in the object from the collection if it is to be included in the returned array.

My solution passes all the checks besides this one: whatIsInAName([{"a": 1, "b": 2, "c": 3}], {"a": 1, "b": 9999, "c": 3}) should return []. And I wonder why the function returns the given array instead of an empty one. And if there is a way to make my function work eventually. My code is gonna be below. THANK YOU FOR HELP!

function whatIsInAName(collection, source) {
  let arr = [];
  const sourceKeys = Object.keys(source);

  for (let key in sourceKeys) {
    arr = collection.filter(
    obj => (Object.keys(obj).length >= sourceKeys.length) ?
    obj.hasOwnProperty(sourceKeys[key]) 
    && obj[sourceKeys[key]] === source[sourceKeys[key]] : 0);
  }

  return arr;
}
whatIsInAName([{"a": 1, "b": 2, "c": 3}], {"a": 1, "b": 9999, "c": 3});

Solution 1:

You could create a simple implementation using Object.keys() and Array.every().

This means each returned item must include each key and value from the source, but may include extra keys and values:

function whatIsInAName(collection, source) {
  return collection.filter(obj => Object.keys(source).every(key => obj[key] === source[key]));
}

console.log(whatIsInAName([{"a": 1, "b": 2, "c": 3}], {"a": 1, "b": 9999, "c": 3}));
console.log(whatIsInAName([{"a": 1, "b": 2, "c": 3}], {"a": 1, "b": 2, "c": 3}));
console.log(whatIsInAName([{"a": 1, "b": 2, "c": 3, "d": 4 }], {"a": 1, "b": 2, "c": 3}));
console.log(whatIsInAName([{"a": 1, "c": 3, "d": 4 }], {"a": 1, "b": 2, "c": 3}));
.as-console-wrapper { max-height: 100% !important; top: 0; }