This code, taken from javascript.ru , searches for all occurrences of the substring "ia":

var str="Ослик ΠΈΠ°-ΠΈΠ° посмотрСл Π½Π° Π²ΠΈΠ°Π΄ΡƒΠΊ"; var poisk="ΠΈΠ°"; var i=0; do { var x = str.indexOf(poisk,i); i=x+1; alert(x) } while (x!=-1) 

The disadvantage of this code is that it goes through one extra iteration when indexOf has already returned -1 . I modified this code as follows:

 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;// Π² ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ ΠΈΡ‚Π΅Ρ€Π°Ρ†ΠΈΠΈ Π½Π°Ρ‡ΠΈΠ½Π°Π΅ΠΌ ΠΎΡ‚ΡΡŽΠ΄Π° } 

I removed the extra iteration, but it turns out that the condition while while never executed in the line with this condition, and the exit from the loop is done by nesting if . The program works, but the code is not logical. Is it possible to remove this inconsistency without complicating the code?

    3 answers 3

    Why don't you do it?

     var str = "Ослик ΠΈΠ°-ΠΈΠ° посмотрСл Π½Π° Π²ΠΈΠ°Π΄ΡƒΠΊ"; var poisk = "ΠΈΠ°"; var x, i = 0; while ((x = str.indexOf(poisk,i)) != -1) { alert(x) i=x+1; } 

    Inside the loop condition, we calculate x and then compare it.

      The problem with while loops is the absence of an initialization block. Because of this, the solution is for them, either to assign assignment to the check in the next answer, or to add if inside the loop in the question.

      Or you can just emulate the initialization block.

      Example for a loop with a postcondition:

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

      Example for a cycle with a precondition

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

      Or just use the for loop.

       var str = "Ослик ΠΈΠ°-ΠΈΠ° посмотрСл Π½Π° Π²ΠΈΠ°Π΄ΡƒΠΊ"; var poisk = "ΠΈΠ°"; for (var x = str.indexOf(poisk, 0); x != -1; x = str.indexOf(poisk, x + 1)) { console.log(x); } 

        The while not without reason, has one expression, which is interpreted as a logical one. Unlike the for loop, it is intended mostly for iterators -

         while( iterator.hasNext() ) { ... } 

        It is also best suited for operations with an object that is changed in the body -

         while( array.length ){ array.pop(); } 

        Or -

         while( array.length < 5 ){ array.push( { } ) ; } 

        do while differs from while only in that its body is guaranteed to be executed once. The first thing that came to mind to demonstrate its work is the specificity of js iterators, which are devoid of the hasNext method -

         let map = new Map(); let iterator = map[Symbol.iterator](); do { let data = iterator.next(); }while( ! data.done ) 

        See how it works? Checking for the next item can be done before getting the current item. It’s the same with the use of while that doesn’t look so beautiful, because for the first time data initialized outside the loop, and if the condition is true, then it continues in the body of the loop -

         let map = new Map(); let iterator = map[Symbol.iterator](); let data = iterator.next(); while( ! data.done ){ data = iterator.next(); } 

        You can do it as below, but I show this code only so that you remember once and for all that you can not do this ! Such lazy code is permissible to write only on forums for example, but in serious projects they criticize for this and leaving this style usually speaks about the person’s experience.

         let map = new Map(); let iterator = map[Symbol.iterator](); let data = null; while( ! ( data = iterator.next() ).done ){ ... } 

        And the most important thing that a newbie needs to say about do while is that he is not used at all in real projects! I have never seen this cycle in cool projects, because the rules for writing code dictate behavior for which this cycle is simply not needed. Therefore, do not bother with it and do not look for ways to use it.