2017-02-20 5 views
0

У меня возникли проблемы с моей петлей .forEach. Вот мой текущий код:ES6 .forEach метод не петля массив?

let isPangram = (phrase) => { 
    let alphabet = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"]; 
    alphabet.forEach(function(letter) { 
    if (phrase.toLowerCase().includes(letter)) { 
     alphabet.splice(alphabet.indexOf(letter), 1); 
    } 
    debugger; 
    }); 
    if (alphabet.length === 0) { 
    return true; 
    } 
    else if (alphabet.length > 0) { 
    return false; 
    } 
}; 

Когда я запускаю это в консоли с debugger, кажется, пропустить некоторые буквы, как b и c. Может ли кто-нибудь сказать мне, что здесь происходит?

+0

Это весело гольф упражнения: 'пусть isPangram = фраза => новый Set (выражение.toLowerCase(). Match (/ [az]/g)). Size === 26; ': D – loganfsmyth

+0

' return alphabet.every (letter => phrase.toLowerCase(). Включает (буква)); 'https://jsfiddle.net/a5w5db66/ – pawel

ответ

1

Вы не должны удалять текущий элемент из массива при повторении с помощью .forEach(). Когда вы удаляете с .splice(), он удаляет элемент, а элементы в массиве впоследствии перемещаются вниз по слоту, а затем следующий шаг итерации пропускает элемент, который только что переместился в текущий слот итерации.

Более безопасный способ сделать это - использовать традиционный циферблат for и повторять его от начала до конца. Затем любые изменения, которые вы делаете в массиве, будут за пределами того, что вы итерируете. Конечно, есть, вероятно, только лучший способ написать это без сращивания вообще. Лично я бы, вероятно, использовал объект Set, чтобы отслеживать все использованные буквы и видеть, закончится ли я со всеми 26 в конце.

От MDN page for .forEach(): «Если элементы, которые уже посещенные удаляются (например, с помощью сдвига()) во время итерации, а затем элементы будут пропущены - смотрите пример ниже.»

Кроме того, forEach() не является чем-то новым в ES6, он присутствует с ES5.


Вот не-делеция способ использовать некоторые функции ES6, чтобы проверить на панграмма:

const allCharsSet = new Set("abcdefghijklmnopqrstuvwxyz"); 
 

 
function isPangram(phrase) { 
 
    let foundLetters = new Set(); 
 
    for (let ch of phrase) { 
 
    \t ch = ch.toLowerCase(); 
 
     if (allCharsSet.has(ch)) { 
 
     \t foundLetters.add(ch); 
 
     } 
 
    } 
 
    return foundLetters.size === allCharsSet.size; 
 
} 
 

 
console.log(isPangram("The five boxing wizards jump quickly.")); 
 
console.log(isPangram("Many-wived Jack laughs at probes of sex quiz.")); 
 
console.log(isPangram("Playing jazz vibe chords quickly excites my wife.")); 
 
console.log(isPangram("some other phrase"));

+0

Спасибо! это имеет большой смысл. Я закончил создание нового массива под названием 'matches', и всякий раз, когда я получил совпадение, я переместил письмо в новый массив, и это сработало. Еще раз спасибо! –

+0

@GeorgeLi - Поскольку вы упомянули ES6, я добавил ES6 способ сделать это, что не нужно удалять вещи из массива. – jfriend00

+0

@GeorgeLi. Поскольку похоже, что вы можете быть здесь новым, если это ответили на ваш вопрос, вы можете указать это сообществу, нажав зеленую галочку слева от ответа. Это также принесет вам некоторые очки репутации, которые могут привести к получению большего количества привилегий на сайте. – jfriend00

Смежные вопросы