2010-06-27 5 views
0

Мне нужно найти, какие идентификационные номера отсутствуют в 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 = {};} 
} 

не проверил, если это рабочий код. :)

+2

Не похоже на то, что вы говорите, что вам вообще нужно. Кроме того, более короткий код не означает лучший код. Более низкая временная сложность или потребность в памяти создают лучший код. – defines

+1

@Dustin Fineout Lower * code * сложность обычно означает «лучший» код в моей книге ... (если есть известная проблема с производительностью, я не забочусь о других :-) – 2010-06-27 15:28:46

+0

Черт, мне нужно получить клиентские номера от пользователей, которые не существует в s.data. Или я слишком долго работал, или я немой. : D – Somebody

ответ

4

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

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

// 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» на самом деле является плоской картой и получила неправильное имя и неполную документацию!

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

Кроме того, вы можете инвертировать CLIENT_ID лет в данном объект ключей и просто проверить ключ существования, которое O (1) против O (п) тогда и только тогда взгляд вверх построен один раз (или, по меньшей мере, намного, гораздо меньше, чем используется), и поэтому он может быть «теоретически» лучше. Размер 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]) { 
    .. 
    } 
} 
+0

Спасибо, друг! Вот что я называю отличным ответом! Жаль, что я могу добавить только 1+ :) – Somebody

Смежные вопросы