HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMinor

Find property and value pairs between two objects

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
objectsvaluepropertybetweentwofindandpairs

Problem

I have a function that looks through an array of objects and returns an array of all objects that have matching property and value pairs. This works fine but I always get the notification: "Don't make functions within a loop".

So is this a bad approach to use a function within a loop?

function where(collection, source) {
  var arr = [];
  var keys = Object.keys(source);
  // What's in a name?
  for(var i = 0; i < collection.length; i++){
     if(keys.every(function(x){return x in collection[i] && source[x] == collection[i][x];})){
       arr.push(collection[i]);
     }
  }

  return arr;
}

where([{ first: "Romeo", last: "Montague" }, { first: "Mercutio", last: null }, { first: "Tybalt", last: "Capulet" }], { last: "Capulet" });

Solution

As @Pimgd explained, it's not good to recreate an anonymous function in every iteration of a loop. Move the function outside of the loop:

function where(collection, source) {
  var arr = [];
  var keys = Object.keys(source);

  function match(x) {
    return x in collection[i] && source[x] == collection[i][x];
  }

  for (var i = 0; i < collection.length; i++) {
     if (keys.every(match)) {
       arr.push(collection[i]);
     }
  }

  return arr;
}


I suggest to go one step further.
Instead of creating an array and appending to it,
you can benefit from the Array.prototype.filter method:

function where(collection, search) {
  function filter(item) {
    function matchSearchValue(key) {
      return key in item && search[key] == item[key];
    }
    return Object.keys(search).every(matchSearchValue);
  }
  return collection.filter(filter);
}


Finally, notice how I renamed everything to better explain their purpose.

Code Snippets

function where(collection, source) {
  var arr = [];
  var keys = Object.keys(source);

  function match(x) {
    return x in collection[i] && source[x] == collection[i][x];
  }

  for (var i = 0; i < collection.length; i++) {
     if (keys.every(match)) {
       arr.push(collection[i]);
     }
  }

  return arr;
}
function where(collection, search) {
  function filter(item) {
    function matchSearchValue(key) {
      return key in item && search[key] == item[key];
    }
    return Object.keys(search).every(matchSearchValue);
  }
  return collection.filter(filter);
}

Context

StackExchange Code Review Q#116114, answer score: 4

Revisions (0)

No revisions yet.