简体   繁体   中英

Count number of objects in array that match another object (javascript only)

right now I'm doing something like this to match objects in an array:

for (var key in users)
{
if (users[key].userID==session)
{
 //do whatever
}
}

but I need to figure out how many times this matches, if it only matches once, then I want it to trigger the event (where it says "//do whatever")

You could use the array.filter method like this:

users.filter(function(a){return (a.userID==session)}).length == 1;

Although the user will need to be running a modern browser (js 1.6) or the filter method be polyfilled.

Simply increment a variable and check if it's == 1 after the loop.

var matched = 0;
for (var key in users) {
    if (users[key].userID==session) {
        matched++;
    }
}

if (matched == 1) {
    // do something
}

This quits looking as soon it finds 2 matches

var count= 0;
for(var key in users){
    if(users[key].userID== session)++count;
    if(count== 2) break;
}
if(count== 1){
    //do whatever
}

if you are worried because performance, you might want to check this out:

function isOnce(itm,arr){
    var first_match=-1;
    for(var i=0,len=arr.length;i<len;i++){
        if(arr[i]===itm){
            first_match=i;
            break;
        }
    }
    if(first_match!=-1){
        var last_match=-1;
        for(i=arr.length-1;i>first_match;i--){
            if(arr[i]===itm){
                last_match=i;
                break;
            }
        }
        if(last_match==-1){
            return true;
        }
    }
    return false;
}

You will notice savings when these two points met:

  • There are 2 or more matches
  • The first and last match are at least 1 space apart

In other words, you don't ever loop on the elements that are between first and last match. So the best case scenario would be:

arr=["a", ...(thousands of items here)... ,"a"];// you only looped 2 times!

I've got a feeling I missed something in your question, but if I understood it properly this should work, and is quite efficient as the loop stops as soon as a second match is found.

var firstMatch = null;

for (var key in users) {
  if (users[key].userID==session) {
    if (firstMatch) { // if a previous match was found unset it and break the loop
      firstMatch = null;
      break;
    } else { // else set it
      firstMatch = users[key];
    }
  }
}

if (firstMatch) {
    doSomethingTo(firstMatch); // maybe you don't need to pass in firstMatch, but it's available if you need to
}

Or the following loop does the same as the one above with a little less code

for (var key in users) {
  if (users[key].userID==session) {
    firstMatch = (firstMatch) ? null : users[key];
    if(!firstMatch) break;
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM