0

I need to create a function that takes in an array of Objects and returns the objects that match a specific set of criteria. What I have so far is fairly simple: (pseudocode)

// input:  conditions: { prop1: "x", prop2: "z"}
//         source: [{ prop1: "x", prop2: "y"}, { prop1: "x", prop2: "z"}];
// output: array of objects with the same properties & values
// ex:
// getObjects({ prop1: "x", prop2: "z"}, [{ prop1: "x", prop2: "y"}, { prop1: "x", prop2: "z"}]);
// returns: [{ prop1: "x", prop2: "z"}]

//....
var results = [];
for (var prop in obj) {
    var match = false;
    for (var cond in conditions) {
        if (cond === prop && conditions[cond] == obj[prop]) {
            match = true;
        }
    }
    if (match) {
        results.push(row);
    }
}
return results;

where conditions is an object that represents one or more properties that the matching object must possess.

The problem is that this is somehow returning duplicate objects, which obviously can't happen. I know there is a standard way to accomplish this (probably a programming 101 kind of thing), but my Google-foo is failing me.

NOTE: I can't use Array.prototype.filter here because of the context. I'm running through a set or rows in a table and only want to return the ones that match certain criteria.

Basically the idea is "return the objects that are similar to the input object.

4
  • Are you sure the resulting duplicate objects are due to this script and not from the query producing the rows from the source table? Commented Apr 28, 2014 at 19:49
  • @DevlshOne: There are not queries involved. The table in question is a <table> manually constructed in markup. Though what I'm essentially doing is a query. Commented Apr 28, 2014 at 20:00
  • Could you provide more detail on the criteria and a sample of table rows? Commented Apr 28, 2014 at 20:04
  • @DevlshOne: Check my updates. Commented Apr 28, 2014 at 20:10

2 Answers 2

2

You were very close from the solution.
If several properties match, you will add the 'row' for each match.
Just add it once per row, after loop on condition and loop on prop ended.
It is a matter of curly brace position :

var results = [];
for (var i =0; i<source.length; i++) {
    var row = source[i];
    var match = true;  
    var samePropCount = 0;
    for (var prop in row) {
        for (var cond in conditions) {
            if (cond === prop ) {
                samePropCount++;
                if (conditions[cond] != row[prop]) {
                   match = false;
                }
            }
        }  
    } 
    if (!samePropCount) match=false;
    if (match) {
        results.push(row);
    }
}
return results;
Sign up to request clarification or add additional context in comments.

4 Comments

The logic of this is flawed. Supposed your object is {a:1, b:2, c:3} and conditions is {a:1, c:4}. As soon as a match is found in {a:1}, match will be set to true. The item will incorrectly be added to results because there is no match for c
from the pseudocode provided, it looks like all properties must match. object { prop1: "x", prop2: "y"} is not in the results when the condition is { prop1: "x", prop2: "z"}
@BrianGlaz you are right, i did not read carefully enough. Now it might be good.
@GameAlchemist: This works great! I knew I was missing something.
0

With underscore:

var evens = _.filter([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
=> [2, 4, 6]

do you want to implement the function?

2 Comments

Basically, yes. But I need it to be able to take in an object that represents what conditions are to be met.
you can pass an array of objects to filter

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.