2009-03-01 6 views
1

J'ai du mal à gérer mes boucles for maintenant, j'essaie de comparer deux datum, fondamentalement, il va comparer deux éléments, puis il va écrire les correspondances et les discordances sur la page Web.Pourquoi ma boucle imbriquée ne fonctionne-t-elle pas comme prévu?

J'ai réussi à écrire les correspondances sur la page Web, ça marchait bien. Mais il y a un bug dans mon incompatibilité comparer.

Il a écrit toutes les données sur les temps page X, voici mon code JS:

function testItems(i1, i2) { 
    var newArray = []; 
    var newArray2 = []; 
    var count = 0; 
    var count2 = 0; 
    for(var i = 0; i < i1.length; i++) { 
     for(var j = 0; j < i2.length; j++) { 
      if(i1[i] == i2[j]) { 
       newArray.push(i1[i]); 
       count++; 
      } if (i1[i] !== i2[j]) { 
       newArray2.push(i1[i]); 
       count2++; 
      } 
     } 
    } 
    count-=2; 
    count2-=2 
    writeHTML(count,count2, newArray, newArray2); 
} 

Le résultat était horrible pour les discordances:

alt text http://www.picamatic.com/show/2009/03/01/07/44/2523028_672x48.jpg

Je l'attendais pour montrer les erreurs, pas toutes les cordes.

+0

Vous devez définir 'match' et 'non-concordance' un peu mieux. Si un item est en i1 et non en i2, est-ce une discordance, ou est-ce que la position importe aussi? – Triptych

+0

Etes-vous aussi intéressé par quelque chose qui est en i2 'mais pas en' i1 '? Si vous êtes alors il vous manque du code pour cela. s'il vous plaît voir ma réponse ci-dessous. –

Répondre

3

La question que vous voyez est en raison de la boucle imbriquée. Vous faites essentiellement une comparaison croisée: pour chaque élément de i1, vous le comparez à chaque élément de i2 (rappelez-vous que j recommence à 0 chaque fois que je avance ... les deux boucles ne fonctionnent pas en parallèle). Depuis que j'ai compris des commentaires ci-dessous que vous voulez pouvoir comparer un tableau à l'autre, même si les articles dans chacun sont dans un ordre différent, j'ai édité ma suggestion originale. Notez que l'extrait ci-dessous ne normalise pas les différences entre les deux tableaux ... Je ne sais pas si c'est un problème. Notez également qu'il compare seulement i1 contre i2 ... pas à la fois i1 à i2 et i2 à i1, ce qui rendrait la tâche un peu plus difficile.

function testItems(i1, i2) { 

    var newArray = []; 
    var newArray2 = []; 

    for (var i = 0; i < i1.length; i++) { 
     var found = false; 
     for (var j = 0; j < i2.length; j++) { 
      if (i1[i] == i2[j]) found = true; 
     } 
     if (found) { 
      newArray.push(i1[i]) 
     } else { 
      newArray2.push(i1[i]) 
     } 
    } 
} 

Comme alternative, vous pourriez envisager d'utiliser une table de hachage à l'index i1/i2, mais étant donné que l'exemple des chaînes dans votre commentaire inclure des espaces et je ne sais pas si vous utilisez des bibliothèques JavaScript d'aide , il est probablement préférable de rester avec les boucles imbriquées. L'extrait ne fait également aucune tentative pour éliminer les doublons.

Une autre optimisation que vous pourriez considérer est que vos tableaux newArray et newArray2 contiennent leur propre propriété de longueur, donc vous n'avez pas besoin de passer le compte à votre éditeur HTML. Lorsque l'écrivain reçoit les tableaux, il peut demander à chacun pour la propriété .length de connaître la taille de chacun.

+0

Salut Jarret, Merci pour votre réponse merveilleuse. Il y a un problème, je veux le comparer mot à mot quel que soit leur ordre. Exemple: 1) Upper Deck New Jersey Nets Vince Carter 2) NBA All-Star vinyle New Jersey Nets Le code ci-dessus va retourner incohérence .. Désolé de ne pas mentionner cela. –

+0

Ah, gotcha! Pas de soucis ... dans ce cas, l'approche de votre nid pour la boucle est très proche. J'ai modifié le code ci-dessus pour refléter un moyen de modifier ce que vous aviez qui pourrait répondre à vos besoins. –

+0

Vous pouvez ajouter un 'break' si une correspondance a été trouvée. – Gumbo

0

J'ai le sentiment que cela a à voir avec votre deuxième comparaison avec « ! == » au lieu de « ! = »

« ! == » est l'inverse de « === », et non " == ". ! == est une comparaison plus stricte qui ne fait aucun type de casting.

Par exemple (5! = '5') est faux, où (5! == '5') est vrai. Cela signifie qu'il est possible que vous puissiez pousser les deux tableaux dans la boucle imbriquée, puisque si (i1 [i] == i2 [j]) et if (i1 [i]! == i2 [j]) peuvent être tous les deux vrais en même temps.

1

pas directement lié à la question, mais vous devriez voir ceci: Google techtalks about javascript

Peut-être vous éclairera :)

+0

vous m'avez cloué, je suis en train de le regarder maintenant. Je l'ai trouvé sur hackersnews –

0

Le problème fondamental ici est qu'une paire de boucles imbriquées est PAS la bonne approche.

Vous devez parcourir un pointeur dans chaque ensemble de données. ONE boucle qui avance à la fois selon les besoins.

Notez que déterminer qui avancer en cas de désadaptation est un problème beaucoup plus important que de simplement les traverser. Trouver la première discordance n'est pas un problème, se remettre sur les rails après l'avoir trouvé difficile.

1

Quelques questions à propos de votre question. Vous devez d'abord utiliser '! =' Au lieu de '! ==' pour vérifier l'inégalité. Deuxièmement, je ne sais pas pourquoi vous faites des décomptes décroissants par 2, suggère à moi qu'il peut y avoir des doublons dans le tableau ?! En tout cas votre logique était fausse, ce qui fut corrigé par Jarrett plus tard, mais ce n'était pas non plus une réponse totalement correcte/complète. Lire à l'avance Votre tâche ressemble à "Deux ensembles de tableaux i1 & i2 pour trouver i1 {intersection} i2 et i1 {tiret} {UNION} i2 {tiret}) (Notation de la théorie des groupes). en newArray et éléments rares dans newArray2.

Vous devez le faire.

1) Supprimer les doublons dans les deux tableaux. (pour améliorer l'efficacité du programme par la suite) (ce n'est pas un MUST pour obtenir le désiré résultat - vous pouvez le passer)

i1 = removeDuplicate(i1); 
i2 = removeDuplicate(i2); 

(L'implémentation pour removeDuplicate n'est pas donnée).

2) Passez par i1 et trouvez i1 {tiret} et i1 {intersection} i2.

var newArray = []; 
    var newArray2 = []; 

    for (var i = 0; i < i1.length; i++) 
    { 
     var found = false; 
     for (var j = 0; j < i2.length; j++) 
     { 
      if (i1[i] == i2[j]) 
      { 
       found = true; 
       newArray.push(i1[i]); //add to i1 {intersection} i2. 
       count++; 
       break; //once found don't check the remaining items 
      } 
     } 

     if (!found)   
     { 
      newArray2.push(i1[i]); //add i1{dash} to i1{dash} {UNION} i2{dash} 
      count2++;[   
     } 
    } 

3) Traversez i2 et i2 {tableau de bord ajoutez} à {tiret} i1

for(var x=0; x<i2.length; x++) 
{ 
    var found = false; 

    //check in intersection array as it'd be faster than checking through i1 
    for(var y=0; y<newArray.length; y++) { 
     if(i2[x] == newArray[y]) 
     { 
     found = true; 
     break; 
     } 
    } 

    if(!found) 
    { 
     newArray2.push(i2[x]); //append(Union) a2{dash} to a1{dash} 
     count2++; 
    } 
} 

writeHTML(count,count2, newArray, newArray2); 
Questions connexes