#javascript
Этот код, взятый с javascript.ru, ищет все вхождения подстроки "иа": var str="Ослик иа-иа посмотрел на виадук"; var poisk="иа"; var i=0; do { var x = str.indexOf(poisk,i); i=x+1; alert(x) } while (x!=-1) Недостаток этого кода в том, что он проходит одну лишнюю итерацию, когда indexOf уже вернул -1. Я модифицировал этот код следующим образом: var string = "JavaScript и Java - разные языки!"; var substring = "Java"; var nextDesiredSubstringPosition = 0; while (desiredSubstringPosition!=-1){ // позиция подстроки, которую мы ищмем var desiredSubstringPosition = string.indexOf(substring, nextDesiredSubstringPosition); if (desiredSubstringPosition === -1 ){break;} nextDesiredSubstringPosition = desiredSubstringPosition + 1;// в следующей итерации начинаем отсюда } Лишнюю итерацию я убрал, но получается что условие при while никогда не выполняется в строке с этим условием, а выход из цикла осуществляется засчет вложенного if. Программа работает, но код не логичный. Можно ли убрать эту нелогичность, не усложняя код?
Ответы
Ответ 1
Почему бы вам не сделать так? var str = "Ослик иа-иа посмотрел на виадук"; var poisk = "иа"; var x, i = 0; while ((x = str.indexOf(poisk,i)) != -1) { alert(x) i=x+1; } Внутри условия цикла вычисляем x и тут же его сравниваем.Ответ 2
Проблема с циклами while, в отсутствии блока инициализации. Из-за этого решение для них, либо как в соседнем ответе выносить присваивание в проверку, либо как в вопросе добавлять if внутрь цикла. Либо можно просто эмулировать блок инициализации. Пример для цикла с постусловием: var str = "Ослик иа-иа посмотрел на виадук"; var poisk = "иа"; var i = 0; var x = str.indexOf(poisk, i); if (x != -1) { do { console.log(x) i = x + 1; x = str.indexOf(poisk, i); } while (x != -1) } Пример для цикла с предусловием var str = "Ослик иа-иа посмотрел на виадук"; var poisk = "иа"; var i = 0; var x = str.indexOf(poisk, i); while (x != -1) { console.log(x) i = x + 1; x = str.indexOf(poisk, i); } Либо просто воспользоваться циклом for var str = "Ослик иа-иа посмотрел на виадук"; var poisk = "иа"; for (var x = str.indexOf(poisk, 0); x != -1; x = str.indexOf(poisk, x + 1)) { console.log(x); }Ответ 3
Цикл while не без причины имеет одно выражение, которое интерпретируется как логическое, он в отличии от цикла for предназначен по большей части для итераторов - while( iterator.hasNext() ) { ... } Так же наилучшим образом подходит операций с изменяемым в теле объектом - while( array.length ){ array.pop(); } Или - while( array.length < 5 ){ array.push( { } ) ; } do while отличается от while лишь тем, что его тело гарантированно выполнится один раз. Первым что пришло в голову чтобы продемонстрировать его работу, это специфичность js итераторов, которые лишены метода hasNext - let map = new Map(); let iterator = map[Symbol.iterator](); do { let data = iterator.next(); }while( ! data.done ) Видите как он устроен? Проверку на следующий элемент можно сделать предварительно получив текущий элемент. Тоже самое ниже с использованием while что выглядит не так красиво, ведь в первый раз data инициализируется за пределами цикла, а если условие правдиво, то уже продолжает в теле цикла - let map = new Map(); let iterator = map[Symbol.iterator](); let data = iterator.next(); while( ! data.done ){ data = iterator.next(); } Можно сделать как ниже, но этот код я показываю лишь для того, чтобы Вы раз и навсегда запомнили что так делать нельзя! Такой ленивый код допустимо писать только на форумах для примера, но в серьёзных проектах за такое ругают и уход от такого стиля обычно говорит об опыте человека. let map = new Map(); let iterator = map[Symbol.iterator](); let data = null; while( ! ( data = iterator.next() ).done ){ ... } И самое главное что нужно сказать о do while новичку, это то что он в реальных проектах вообще не используется! Ни одного раза не видел в крутых проектах этот цикл, потому-что правила написания кода диктует поведение, для которого этот цикл просто не нужен. Поэтому не заморачивайтесь на нем и не ищите способы его применения.
Комментариев нет:
Отправить комментарий