Как уменьшить этот цикл сравнения - PullRequest
0 голосов
/ 27 июня 2010

Мне нужно найти, какие номера идентификаторов отсутствуют в s.data по сравнению с пользователями.Есть ли лучший (меньший код) способ сравнения?

Спасибо;)

if(users.length != undefined)
{

    for(y=0;y<users.length;y++) 
    {
        var left = true;
        for(y2=0;y2<s.data.length;y2++) 
        {
            if(users[y].client_id==s.data[y2].client_id) {left = false;break;}
        }
        if(left) {users[y].ref.remove();delete users[y];}

    }

}
else if(!jQuery.isEmptyObject(users))
{
    var left = true;
    for(y2=0;y2<s.data.length;y2++) 
    {
        if(users.client_id==s.data[y2].client_id) {left = false;break;}
    }
    if(left) {users.ref.remove();users = {};}
}

Не проверяли, работает ли этот код.:)

1 Ответ

4 голосов
/ 27 июня 2010

Во-первых, выкл, 2-я ветвь кажется не чем иным, как специализацией первой ветви. Вы можете использовать это либо для создания "2nd" users = [users] (в этом случае пользователи действительно означают пользователей, а не a-user), а полностью исключает верхнюю ветвь , либо удаляет логику в вызываемой функции. для каждого пользователя.

Теперь, чтобы заняться внутренним циклом: что такое «карта» и «содержит». Глядя на это только с точки зрения содержит:

// Returns true if any item in data.client_id (an array)
// is that of user.client_id
function dataContains (user, data) {
  for (var i = 0; i < data.length; i++) {
    if (data[i].client_id == user.client_id) {
      return true
    }
  }
  return false
}

Теперь код уменьшен до:

for (each user) {
  if (!dataContains(user, data)) {
    // do something here
  }
}

Однако мы могли бы пойти еще дальше и использовать общее «содержит», если у нас также есть «карта». Окончательная форма тогда:

var dataIds = map(data, function (x) { return x.client_id })
for (each user) {
  if (!contains(user.client_id, dataIds)) {
    ..
  }
}

Где «содержит» гораздо более обобщенно:

// Returns true iff item is contained within arr
function contains (item, arr) {
  // Just do what the comment documentation says
}

Если вы используете jQuery, у вас уже есть удобные функции: 'содержит' - inArray и "sorta" 'map' - map . Однако, будьте осторожны! JQuery 'map' - это действительно плоская карта, которой присвоено неправильное имя и неполная документация!

Я считаю, что в ECMAScript ED5 эти функции стандартны.

Кроме того, вы можете инвертировать значения client_id в данных в ключи объекта и просто проверять наличие ключа, то есть O (1) против O (n) тогда поиск создается один раз ( или, по крайней мере, намного, намного меньше, чем это используется) и поэтому это может быть "теоретически" лучше. Размер n имеет большое значение, если это действительно имеет значение, если вообще имеет значение. В этом случае вполне вероятно, что поиск может быть построен постепенно и сохранен между временами выполнения этого кода.

var existingIds = {}
for (var i = 0; i < data.length; i++) {
  existingIds[data[i].client_id] = true
}
for (each user) {
  if (!existingIds[user.client_id]) {
    ..
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...