John John - 4 months ago 7
Javascript Question

Using pure JavaScript, given a collection of objects and a filter object, return objects in collection with same key/value pair as the filter object

I have a pseudo-code for solving a certain problem in JavaScript but I can't seem to wrap my head on how to translate it to code:

var sampleCollection = [
{ 'a': 1, 'b': 2, 'c': 3 },
{ 'a': 4, 'b': 5, 'c': 6 }
];

var sampleFilter = { 'a': 4, 'c': 6 };

function getCollectionFilter(collection,filter) {
function collectionFilter(collection,filter) {
//return if for each element in filter,
//collection's key/value pair is same with filter's key/value pair
}

return collection.filter(collectionFilter);
}

getCollectionFilter(sampleCollection,sampleFilter);
// -> { 'a': 4, 'b': 5, 'c': 6};


I think lodash has the _.matches to solve this, but I would like to know why things are done in certain ways and what are the implications/consequences if done otherwise.

Bonus for giving context in the real world on why a solution/practice is "best"

Answer

Use Array#filter and Array#every methods

var sampleCollection = [{
  'a': 1,
  'b': 2,
  'c': 3
}, {
  'a': 4,
  'b': 5,
  'c': 6
}];

var sampleFilter = {
  'a': 4,
  'c': 6
};

function getCollectionFilter(collection, filter) {
  // filter out elements and return
  return collection.filter(function(v) {
    // get all object keys 
    return Object.keys(filter)
      // use `every` method and check all values are equal
      .every(function(k) {
        // compare values
        return filter[k] == v[k];
      });
  })
}
console.log(
  getCollectionFilter(sampleCollection, sampleFilter)
);


With ES6 arrow function you can make it one line.

var sampleCollection = [{
  'a': 1,
  'b': 2,
  'c': 3
}, {
  'a': 4,
  'b': 5,
  'c': 6
}];

var sampleFilter = {
  'a': 4,
  'c': 6
};

function getCollectionFilter(collection, filter) {
  return collection.filter(v => Object.keys(filter).every(k => filter[k] == v[k]))
}
console.log(
  getCollectionFilter(sampleCollection, sampleFilter)
);