3

I am trying to search for an object in an array of objects.

Note, vals and recs objects will be DYNAMIC.

var vals = {ID: "4", LOC: "LA", SEQ: "1"};

var recs = [
  {ID:"4", LOC:"LA", SEQ:"1"},
  {ID:"4", LOC:"NY", SEQ:"1"},
  {ID:"4", LOC:"CHI",SEQ:"1"}

];

Now I need to check if all key:value pairs in vals already exist in recs . In this case, recs[0] is an exact match of vals.

Heres my attempt:

var vals =  {ID: "4", LOC: "LA", SEQ: "1"};


var recs = [
  {ID:"4", LOC:"LA", SEQ:"1"},
  {ID:"3", LOC:"NY", SEQ:"2"},
  {ID:"2", LOC:"CHI",SEQ:"3"}

];


for(var i = 0; i<recs.length; i++){  
    if(recs[i]["ID"] == vals["ID"] && recs[i]["LOC"] == vals["LOC"] && recs[i]["SEQ"] == vals["SEQ"]){
      console.log(true);
    }
    else{
      console.log(false);
    }  
}

The above works only because I have hardcoded the keys from the vals object. In reality, the VALS object (and recs) will be DYNAMIC with X number of key:value pairs.

So how can I modify my for loop for a dynamic vals object?

thanks!

3
  • 1
    So loop over the keys. var keys = Object.keys(vals); Commented Mar 17, 2016 at 0:40
  • from someone who has done this a lot: Object.keys() is very fast, so comparing the length of each object's key array would be a fast way of eliminating misfits. sorting and joining those keys into a string provides a fast membership comparison. if both those quick tests pass, iterate and compare values. of course, if perf doesn't matter, just do two unfiltered nested loops and KISS. Commented Mar 17, 2016 at 0:51
  • the question is vuage. does {a:1} describe {a:1,b:2}? should it return the first result, all matches or a boolean? Commented Mar 17, 2016 at 0:56

6 Answers 6

1

Try this:

for (var i = 0; i < recs.length; i++) {  
  var found = true;
  for (var p in vals) {
    if (vals.hasOwnProperty(p)) {
      if (recs[i][p] !== vals[p]) {
        found = false;
        break;
      }
    }
  }
  console.log(found);
}
Sign up to request clarification or add additional context in comments.

1 Comment

gimme a break for perf
1
for(var i = 0; i<recs.length; i++) {  
    for (var prop in object) {
       if (recs[i][prop] != vals[prop]) {
           console.log(false);
           return;
       }

    }
    //check from both sides
    for (var prop in vals) {
       if (recs[i][prop] != vals[prop]) {
           console.log(false);
           return;
       }

    }
    console.log(true);


}

1 Comment

shape mismatches will throw with this pattern. be careful what you iterate into when fetching properties
1

You could iterate over the keys; something along the lines of:

var vals = {  ID: "4",  LOC: "LA",  SEQ: "1", REGION: "USA" };


var recs = [{    ID: 4,    LOC: "LA",    SEQ: "1",    REGION: "USA"  },
            {    ID: 3,    LOC: "NY",    SEQ: "2",    REGION: "USA"  },
            {    ID: 2,    LOC: "CHI",    SEQ: "3",    REGION: "USA" }

];

var isSame = true;

for (var i = 0; i < recs.length; i++) {
  console.log( i + '----------------' );
  var isSame = true;
  
  // get the keys of the record
  var keys = Object.keys(recs[i]);

  for (var j = 0; j < keys.length; j++) {
    
    var key = keys[j];
    var record = recs[i] 
    
    console.log( key + ": " + record[key] + '=' + vals[key] );   
    
    if (record[key] != vals[key] ) {                                
        isSame = false;// not equal
        break;
    }
  }

  console.log('isSame: ' + isSame );
  console.log('------------------' );
}

2 Comments

might want to memorize keys[j] and or recs[i] when you use them so often to shorten and hasten.
Good point; I'll update the answer when I get back to my desk... Thx @dandavis
1

You need to break it into two loops, one for each object of the array and one for each key of the object:

for(var i = 0; i<recs.length; i++){  
  var found = false
  for(var key in recs[i]) {
    if(recs[i].hasOwnProperty(key)){
      if(recs[i][key] != vals[key]){
        found = true
      }
    }
  console.log(found)
}

the hasOwnProperty call will make sure it doesn't break if the object does not have that key.

1 Comment

where does the vals.key come from? you need vals[key] et al
0

You can try this:

function myFind(recs, vals) {
    return recs.some(function(obj) {
        for (var x in obj)
            if (x in vals && obj[x] != vals[x])
                return false;
        return true;
    });
}

var recs = [
    {ID:4, LOC:"LA", SEQ:"1", USA:"USA"},
    {ID:3, LOC:"NY", SEQ:"2", USA:"USA"},
    {ID:2, LOC:"CHI",SEQ:"3", USA:"USA"}
];

var vals =  {ID: "4", LOC: "LA", SEQ: "1"};

if (myFind(recs, vals)) {
    alert('found');
} else {
    alert('not found');
}

Hope it helps.

6 Comments

This won't find the item. The object references are different.
@EvanTrimboli. I didn't see the second declaration of recs sorry for that, I've updated now
That edit won't find the value either. The references still won't be the same, with the added downside of mutating the values in recs.
@EvanTrimboli. Strange, It works here, I will add an snippet
why are you using delete ?
|
0

you can use underscorejs isEqual for this kind of problem

Comments

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.