2017-02-17 15 views
0

У меня есть следующий код:Изменяя массив в то время как итерация

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

И я wounder как бы я до сих пор продолжаю внешнюю итерацию, даже если я меняюсь размером с сращиванием. Я читал, что могу добиться этого с помощью обратной итерации, но это решение работает только для одного цикла, а не для двух.

Спасибо.

+0

вам нужно изменить 'i', а также, чтобы отразить это правильное положение в отношении изменения вы сделали – njzk2

+0

Просто используйте' words.splice (0 , 1); 'или просто' words.shift(); 'вместо этого. – Xufox

+2

Я не понимаю смысл вашего внешнего цикла – njzk2

ответ

0

Если вы удаляете элементы, было бы лучше перебрать массив позади.

Из нашего обсуждения вам нужно сравнить элемент друг с другом и на основе некоторой бизнес-логики (представленной как случайный 10% в приведенном ниже коде) будет отклонять слово из поставляемого массива.

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


ОБНОВЛЕНИЕ ДЛЯ ЭФФЕКТИВНОСТЬ

Upon думать об этом дальше, рекурсивная функция кажется более эффективное решение, чем один из приведенных выше , Выше всего continue - любой элемент, с которым он сталкивается, с индексом undefined. Таким образом, мы по-прежнему получаем доступ к элементам n^2 при обработке. В качестве альтернативы, если мы передаем текущий список слов в рекурсивную функцию в качестве аргумента, вместе с wordA, чтобы сравнить ее с, мы можем уменьшить попытки отрицания доступа к удаленным словам, ускоряя последующие итерации по мере удаления элементов.

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

Это возвращает undefined –

+0

@CelixOderix, обновленный (опечатка с отсутствующим '-1') – haxxxton

+0

Я проверяю, является ли тот же объект с' if (Object.is (word, words [i])) continue', i подумайте, что это проблема, вы знаете, почему? –