Подсчитать количество объектов в массиве, которые соответствуют другому объекту (только JavaScript) - PullRequest
2 голосов
/ 13 февраля 2012

сейчас я делаю что-то вроде этого для сопоставления объектов в массиве:

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

но мне нужно выяснить, сколько раз это совпадение, если оно совпадает только один раз, тогда я хочу этовызвать событие (где написано "// делать что угодно")

Ответы [ 5 ]

4 голосов
/ 13 февраля 2012

Вы можете использовать метод array.filter следующим образом:

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

Хотя пользователь должен будет запустить современный браузер (js 1.6) или метод фильтрации должен быть заполнен.

2 голосов
/ 13 февраля 2012

Это прекращает поиск, как только он находит 2 совпадения

var count= 0;
for(var key in users){
    if(users[key].userID== session)++count;
    if(count== 2) break;
}
if(count== 1){
    //do whatever
}
2 голосов
/ 13 февраля 2012

Просто увеличьте переменную и проверьте, является ли она == 1 после цикла.

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

if (matched == 1) {
    // do something
}
1 голос
/ 13 февраля 2012

если вы беспокоитесь о производительности, вы можете проверить это:

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;
}

Вы заметите экономию, когда эти два пункта встретятся:

  • Есть 2 или более совпадений
  • Первое и последнее совпадения расположены на расстоянии как минимум 1 пробел

Другими словами, вы никогда не зацикливаетесь на элементах, которые находятся междупервый и последний матч.Таким образом, лучший сценарий будет:

arr=["a", ...(thousands of items here)... ,"a"];// you only looped 2 times!
0 голосов
/ 13 февраля 2012

У меня такое чувство, что я что-то пропустил в вашем вопросе, но если я правильно понял, это должно сработать, и это будет весьма эффективно, поскольку цикл останавливается, как только найдено второе совпадение.

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
}

Или следующий цикл делает то же, что и выше, с чуть меньшим кодом

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