最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Why is my nested for loop not working as I expected? - Stack Overflow

programmeradmin8浏览0评论

I have trouble dealing with my for loops now, I'm trying to pare two datum, basically it will pare 2 items, then it will write the matches and the mismatches on the webpage.

I managed to write the matches on the webpage, it was working good. But there's a bug in my mismatch pare.

It wrote all the data on the webpage X times, here's my JS code:

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

The result was horrible for the mismatches:

alt text .jpg

I was expecting it to show the mistakes, not all the strings.

I have trouble dealing with my for loops now, I'm trying to pare two datum, basically it will pare 2 items, then it will write the matches and the mismatches on the webpage.

I managed to write the matches on the webpage, it was working good. But there's a bug in my mismatch pare.

It wrote all the data on the webpage X times, here's my JS code:

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

The result was horrible for the mismatches:

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

I was expecting it to show the mistakes, not all the strings.

Share Improve this question edited Mar 31, 2009 at 14:26 GEOCHET 21.3k15 gold badges77 silver badges99 bronze badges asked Mar 1, 2009 at 16:50 Raymond G.Raymond G. 652 silver badges9 bronze badges 2
  • You need to define 'match' and 'mismatch' a little better. If an item is in i1 and not in i2 is it a mismatch, or does position also matter? – Kenan Banks Commented Mar 1, 2009 at 16:58
  • Are you also interested in something that is in i2' but not in 'i1'? If you are then you are missing code for it. please see my answer below. – Real Red. Commented Mar 2, 2009 at 14:38
Add a ment  | 

5 Answers 5

Reset to default 3

The issue you're seeing is because of the nested for loop. You are essentially doing a cross-pare: for every item in i1, you are paring it to every item in i2 (remember that j starts again at 0 every time i advances... the two loops don't run in parallel).

Since I understand from the ments below that you want to be able to pare one array to the other, even if the items in each are in a different order, I've edited my original suggestion. Note that the snippet below does not normalize differences in case between the two arrays... don't know if that's a concern. Also note that it only pares i1 against i2... not both i1 to i2 and i2 to i1, which would make the task a little more challenging.

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])
        }
    }
}

As an alternative, you could consider using a hash table to index i1/i2, but since the example of strings in your ment include spaces and I don't know if you're using any javascript helper libraries, it's probably best to stick with the nested for loops. The snippet also makes no attempt to weed out duplicates.

Another optimization you might consider is that your newArray and newArray2 arrays contain their own length property, so you don't need to pass the count to your HTML writer. When the writer receives the arrays, it can ask each one for the .length property to know how large each one is.

Not directly related to the question but you should see this: Google techtalks about javascript

Maybe it will enlighten you :)

Couple of things about your question. First you should use '!=' instead of '!==' to check inequality. Second I am not sure why you are doing decreasing counts by 2, suggests to me that there may be duplicates in the array?! In any case your logic was wrong which was corrected by Jarrett later, but that was not a totally correct/plete answer either. Read ahead.

Your task sounds like "Given two set of arrays i1 & i2 to find i1 {intersection} i2 and i1{dash} {UNION} i2{dash}) (Group theory notation). i.e. You want to list mon elements in newArray and unmon elements in newArray2.

You need to do this.

1) Remove duplicates in both the arrays. (For improving the program efficiency later on) (This is not a MUST to get the desired result - you can skip it)

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

(Implementation for removeDuplicate not given).

2) Pass through i1 and find i1{dash} and 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) Pass through i2 and append i2{dash} to i1{dash}

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

I have a feeling that this has to do with your second parison using "!==" instead of "!="

"!==" is the inverse of "===", not "==". !== is a more strict parison which does not do any type casting.

For instance (5 != '5') is false, where as (5 !== '5') is true. This means it's possible that you could be pushing to both arrays in the nested loop, since if(i1[i] == i2[j]) and if(i1[i] !== i2[j]) could both be true at the same time.

The fundamental problem here is that a pair of nested loops is NOT the right approach.

You need to walk a pointer through each dataset. ONE loop that advances both as needed.

Note that figuring out which to advance in case of a mismatch is a much bigger problem than simply walking them through. Finding the first mismatch isn't a problem, getting back on track after finding it is quite difficult.

发布评论

评论列表(0)

  1. 暂无评论