2010-06-27 4 views
0

J'ai besoin de trouver les numéros d'identification qui manquent dans les données par rapport aux utilisateurs. Existe-t-il un meilleur moyen de comparaison (code plus petit)?Comment réduire cette boucle de comparaison

Merci;)

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

ai pas vérifié si cela est le code de travail. :)

+2

Ne semble pas faire ce dont vous avez besoin du tout. En outre, un code plus court ne signifie pas un meilleur code. Une complexité de temps moindre ou une exigence de mémoire crée un meilleur code. – defines

+1

@Dustin Fineout * code * complexité signifie normalement "meilleur" code dans mon livre ... (sauf s'il y a un problème de performance connu, je me soucie pas des autres :-) –

+0

Merde j'ai besoin d'obtenir les numéros client_id des utilisateurs qui n'existe pas dans s.data. Ou je travaillais trop longtemps ou je suis bête. : D – Somebody

Répondre

4

D'abord, off, la 2ème branche ne semble être qu'une spécialisation de la première branche. Vous pouvez l'utiliser pour faire le "2ème" users = [users] (dans ce cas, les utilisateurs signifient vraiment les utilisateurs et non un utilisateur) et élimine la branche supérieure entièrement, ou supprimer la logique dans une fonction appelée par utilisateur. Maintenant, pour aborder la boucle interne: Qu'est-ce que c'est une «carte» et un «contient». En regardant juste en termes de contient:

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

Maintenant, le code est réduit à:

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

Cependant, nous pourrions franchir une étape supplémentaire et d'utiliser un générique « contient » si nous avons aussi une carte'. La forme finale est alors:

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

Lorsque le 'contient' est beaucoup plus généralisé:

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

Si vous utilisez jQuery vous avez déjà des fonctions pratiques: CONTAINS - inArray, et "sorta" 'carte' - map. Cependant, soyez averti! La «carte» de jQuery est vraiment une carte plate et a reçu un nom incorrect et une documentation incomplète! Je crois que ECMAScript ED5 a ces fonctions standard. Je crois que ECMAScript ED5.

En outre, vous pouvez inverser les années client_id dans les données objet clés et tester simplement l'existence clé, qui est O (1) par rapport à O (n) ssi le look-up est construit une fois (ou au moins beaucoup, beaucoup moins que c'est utilisé) et donc il peut être "théoriquement" meilleur. La taille de n fait une grande différence si cela compte réellement, voire pas du tout. Dans ce cas, il est probable que la recherche puisse être construite de manière incrémentielle et sauvegardée entre l'exécution de ce code.

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

Merci mon pote! C'est ce que j'appelle une excellente réponse! Dommage que je puisse ajouter seulement 1+ :) – Somebody

Questions connexes