2017-02-17 4 views
0

Ich habe den folgenden Code:Array Ändern während iterieren

for (let word in words) { 
    for (let i = 0; i < words.length; i++) { 
    // something 
    words.splice(i, 1); 
    i--; 
    } 
} 

und ich bin wounder wie könnte ich noch die äußere Iteration fortsetzen, auch wenn ich die Größe mit Splice bin zu ändern. Ich habe gelesen, dass ich das mit einer umgekehrten Iteration erreichen kann, aber diese Lösung funktioniert nur für eine Schleife, nicht für zwei.

Danke.

+0

Sie müssen 'I' auch verändern zu reflektieren sie über die Änderung bezüglich richtigen Position ist Sie – njzk2

+0

einfach gemacht verwenden' words.splice (0 , 1); oder einfach 'words.shift();' stattdessen. – Xufox

+2

Ich verstehe nicht den Punkt Ihrer äußeren Schleife – njzk2

Antwort

0

Wenn Sie Elemente entfernen, ist es am besten, das Array rückwärts zu durchlaufen.

Aus unserer Diskussion müssen Sie das Element mit jedem anderen Element vergleichen, und basierend auf einer Geschäftslogik (dargestellt als zufällige 10% im folgenden Code) wird ein Wort aus dem gelieferten Array zurückgewiesen.

JS

let words = ["one", "two", "three", "four", "five", "six"]; // 100.000 strings 

for (let x = words.length - 1; x >= 0; x--) { 
    // if we're trying to access an element that no longer exists 
    if (typeof words[x] === 'undefined') continue; 
    for (let y = words.length - 1; y >= 0; y--) { 
     // if we're trying to access an element that no longer exists 
     if (typeof words[y] === 'undefined') continue; 
     // if word should be rejected 
     console.log('Comparing: ' + words[x] + ' ' + words[y]); 
     if (shouldRejectWordB(words[x], words[y])) { 
      // remove the word 
      console.log('Rejecting: ' + words[y]); 
      words.splice(y, 1); 
     } 
    } 
} 
console.log(JSON.stringify(words)); 

function shouldRejectWordB(wordA, wordB) { 
    // reject word randomly 
    if (Math.random() < 0.1) { 
     return true; 
    } else { 
     return false; 
    } 
} 

JS FIDDLE


UPDATE FÜR EFFIZIENZ

Bei einer weiteren darüber nachgedacht, eine rekursive Funktion scheint wie eine effizientere Lösung als zuvor . Oben einfach continue 's irgendein Element, das es trifft, das an einem undefined Index ist. Daher greifen wir immer noch auf n^2 Elemente zu, während wir sie verarbeiten. Alternativ können wir, wenn wir die aktuelle Wörterliste in eine rekursive Funktion als Argument übergeben, zusammen mit wordA die negativen Versuche reduzieren, auf entfernte Wörter zuzugreifen, was spätere Iterationen beschleunigt, wenn Elemente entfernt werden.

JS

let words = ["one", "two", "three", "four", "five", "six"]; // 100.000 strings 

function shouldRejectWordB(wordA, wordB) { 
    // reject word randomly 
    if (Math.random() < 0.1) { 
     return true; 
    } else { 
     return false; 
    } 
} 

function compareWordAToEachWord(wordA, words){ 
    // loop through each provided word 
    for (let y = words.length - 1; y >= 0; y--) { 
     // if word should be rejected 
     console.log('Comparing: ' + wordA + ' ' + words[y]); 
     var wordToCompare = words[y]; 
     if (shouldRejectWordB(wordA, wordToCompare)) { 
      // remove the word 
      console.log('Rejecting: ' + wordToCompare); 
      words.splice(y, 1); 
      // if we just rejected the word that is currently set as wordA stop comparing this loop 
      if(wordToCompare === wordA){ 
       break; 
      } 
     } 
    } 
    if(words.length){ 
     // the index of the current wordA 
     var index = words.indexOf(wordA); 
     // suggested index of the next word 
     var newIndex = words.length - 1; 
     console.log('index: '+index+' suggestion: '+newIndex); 
     // if the suggestion is the same or greater than the current word, get the item before the current word 
     if(index <= newIndex){ 
      newIndex = index-1; 
     } 
     // if our suggestion is not for an element before the first (ie. invalid), begin another comparison 
     if(newIndex >= 0){ 
      compareWordAToEachWord(words[newIndex], words); 
     }else{ 
      // we have completed out looping through all words for comparison 
      console.log(JSON.stringify(words)); 
     } 
    } 
} 

console.log(JSON.stringify(words)); 
// kick start the comparison with the last word in the list 
compareWordAToEachWord(words[words.length - 1], words); 

UPDATED FIDDLE

+0

Dies ist zurück undefined –

+0

@CelixOderix, aktualisiert (Tippfehler mit dem fehlenden '-1') – haxxxton

+0

Ich überprüfe, ob das gleiche Objekt ist mit 'if (Object.is (Wort, Wörter [i])) continue', ich denke, das ist das Problem, weißt du warum? –