Pętle

Pętlę w programowaniu pozwalają nam wykonywać dany kod pewną ilość razy.

Przypuśćmy, że byliśmy niegrzeczni i nauczyciel kazał nam napisać jakieś zdanie 100 razy. Możemy to oczywiście zrobić za pomocą poniższego kodu:


console.log("Nie będę rozmawiał na lekcji Informatyki.");
console.log("Nie będę rozmawiał na lekcji Informatyki.");
console.log("Nie będę rozmawiał na lekcji Informatyki.");
console.log("Nie będę rozmawiał na lekcji Informatyki.");
console.log("Nie będę rozmawiał na lekcji Informatyki.");
...

Ale o wiele lepiej jest skorzystać z pętli, która wykona dany kod zadaną liczbę razy.

Pętla typu for

Jednym z najczęściej stosowanych typów pętli jest pętla typu for


for (zainicjowanie licznika;  wyrażenie testujące koniec pętli;  zwiększenie/zmniejszenie licznika) {
    kod który zostanie wykonany pewną ilość razy
}

Przykładowo:


for (let x=0; x<100; x++) {
    console.log('Nie będę rozmawiał na lekcji Informatyki.');
}

W każdej pętli mamy dostęp do jej licznika:


let sum = 0;
for (let i=0; i<10; i++) {
    sum += i;
}
console.log(sum); //wypisze 45

Pętle spokojnie mogą odliczać w przeciwnym kierunku:


let str = "";
for (let i=5; i>0; i--) {
    str += "Trwa odliczanie: "+i+" \n";
}
console.log(str);

Pętla typu while

Pętla while to kolejny typ pętli stosowany w JS. Struktura tej pętli ma następującą postać:


while (wyrażenie-sprawdzające-zakończenie-pętli) {
    ...fragment kodu który będzie powtarzany...
}

Zauważ, że w pętli tego typu nie definiujemy ani początkowego licznika, ani nie definiujemy zmiany licznika. Musimy te rzeczy zrobić ręcznie:


let i = 1;

while (i <= 100) {
    console.log("Nie będę...");
    i++;
}

Jeżeli w powyższym kodzie pętli nie zwiększalibyśmy zmiennej i, wówczas pętla ta wykonywała by się w nieskończoność (infinite loop), co zaowocowało by "zawieszeniem" strony.

Pętla w pętli

Czasami musimy wykonać zadania "n - wymiarowe". Dla przykładu przy wypisywaniu tabliczki mnożenia musimy utworzyć 10 kolumn z 10 komórkami. Do takich działań stosujemy pętle w pętlach.

Popatrz na powyższe przykłady. Pętla zaczyna się "kręcić", wykonując swój wewnętrzny kod. W powyższych przykładach to tylko jedna linijka console.log. Ale przecież takich linii kodu, który ma powtarzać pętla może być dowolnie wiele. Co więcej - wśród tych linii mogą być zagnieżdżone pętle, które przy każdym przebiegu głównej pętli wykonają swój kod naście razy.


for (let i=0; i<10; i++) {

    console.log('%c Główna pętla nr: ' + i, 'color:red');

    for (let y=0; y<6; y++) {
        console.log('%c Pętla wewnętrzna nr: ' + y, 'color:blue');
    }

}

Działanie powyższego skryptu ma postać:

Jak widzisz główna pętla zaczyna działać wykonując po kolei kolejne linie kodu. Wypisuje więc w konsoli jedną czerwoną linijkę. Kod dochodzi do wewnętrznej pętli. Ta zaczyna działać. Po jej zakończeniu kończy się działanie jednej iteracji głównej pętli. Rozpoczyna się druga iteracja... Co ważne, wewnętrzne pętle mają dostęp do liczników pętli zewnętrznych.

Bardzo ważne jest by pętle wewnętrzne miały inny licznik niż główna pętla. W przeciwnym razie praktycznie zawsze czeka cię zawieszenie strony.

Przykłady użycia pętli

Powiedzmy, że chcemy w konsoli wypisać tekst:

******

Wykorzystajmy do tego pętlę:


let str = '';

for (let j=0; j<6; j++) {
    str += '*';
}

console.log(str);

Dodajemy kolejny poziom skomplikowania. Załóżmy, że chcemy wypisać w konsoli poniższy tekst:

******
******
******
******

Użyjmy do tego pętli w pętli:


let str = '';

for (let i=0; i<3; i++) {
    for (let j=0; j<6; j++) {
        str += '*';
    }
    str += "\n";
}

console.log(str);

Pozostaje poziom hard. Załóżmy że chcemy w konsoli wypisać:

******
*----*
*----*
******

Użyjmy do tego pętli w pętli, w której zbadamy dane liczniki:


let str = '';

for (let i=0; i<4; i++) {
    for (let j=0; j<6; j++) {
        if (i==0 || i>=3 || j==0 || j>=5) {
            str += '*';
        } else {
            str += '-';
        }
    }
    str += "\n";
}

console.log(str);

Pętle wykonywane po tablicach

Nie zawsze wiemy ile dany obiekt ma elementów, i ile razy nasza pętla się wykona.

Przypuśćmy, że mamy tablicę. Aby zrobić po niej pętle posłużymy się właściwością length, która zwraca długość tablicy (liczbę elementów które zawiera dana tablica):


const tab = ['element 1', 'element 2', 'element 3'];

...tutaj zmieniamy długość tablicy...

for (let i=0; i<tab.length; i++) {
    console.log( tab[i] );
}

Ta sama zasada tyczy się przy pracy z pobranymi ze strony elementami. Gdy pobieramy takie elementy, często nie wiemy ile ich jest. Wystarczy zrobić więc pętle po takiej "tablicy":


const p = document.querySelectorAll('p'); //pobieramy wszystkie paragrafy z dokumentu

for (let i=0; i<p.length/2; i++) {
    p[i].classList.add('important') //wszystkim paragrafom ustawiam klasę .important
}

Trening czyni mistrza

Poniżej zamieszczam kilka zadań, które w ramach ćwiczenia możesz wykonać:

  1. Za pomocą pętli wypisz w konsoli tekst
    ******
    Gwiazdki powinny być w jednej linii. Skorzystaj tutaj z dodatkowej zmiennej str.
    
                let str = "";
                for (var i=0; i<6; i++) {
                    str += "*";
                }
                console.log(str);
                
            
  2. Za pomocą pętli wypisz w konsoli tekst
    12345678910
    
                let str = "";
                for (var i=1; i<=10; i++) {
                    str += i;
                }
                console.log(str);
                
            
  3. Za pomocą pętli w pętli wypisz w konsoli tekst:
    ******
    ******
    ******
    ******
    
                let str = "";
                for (var i=0; i<6; i++) {
                    for (var j=0; j<6; j++) {
                        str += "*";
                    }
                    str += "\n";
                }
                console.log(str);
                
            
  4. Za pomocą pętli (nie musi być pojedyncza) wypisz w konsoli tekst:
    ╔═══════════════════════╗
    ║  To jest jakiś tekst  ║
    ╚═══════════════════════╝

    W razie czego długość tekstu pobierzesz za pomocą konstrukcji:

    
            "Ala ma kota".length //11
            
    
                const text = "Ala ma kota";
                let str = "";
    
                //gora
                str += "╔";
                //do długości tekstu dodajemy 4 spacje oddzielające go od bocznych krawędzi
                for (var i=0; i<text.length+4; i++) {
                    str += "═";
                }
                str += "╗\n";
    
                //srodek
                str += "║  " + text + "  ║\n";
    
                //dol
                str += "╚";
                //do długości tekstu dodajemy 4 spacje oddzielające go od bocznych krawędzi
                for (var i=0; i<text.length+4; i++) {
                    str += "═";
                }
                str += "╝\n";
    
                console.log(str);