Pętle for i while

Pętle w programowaniu pozwalają nam wykonywać dany kod zadaną 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.

Poniżej zajmiemy się klasycznymi pętlami, które istnieją w większości języków - w tym w Javascript.

Pętla typu for

Jednym z najczęściej stosowanych typów pętli jest instrukcja for.


for (zainicjowanie_zmiennych;  warunek_kończący_wykonywanie_pętli;  zmiana_zmiennych) {
    kod który zostanie wykonany pewną ilość razy
}

Pętle takie najczęściej stosuje się w sytuacjach, kiedy dokładnie znamy liczbę powtórzeń - od - do:


//pętla od 0 do 99
for (let i=0; i<100; i++) {
    console.log("Nie będę rozmawiał na lekcji Informatyki.");
}

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


for (let i=0; i<10; i++) {
    console.log("Wykonanie pętli ", i);
}

let sum = 0;

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

console.log(sum); //45

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


for (let i=10; i>0; i--) {
    console.log("Trwa odliczanie", i);
}

A sam warunek kończący wcale nie musi wyglądać jak powyżej:


const a = 10;
const b = 20;

for (let i=1; i<=a && i<=b; i++) {
    //bo oba muszą być prawdziwe
    console.log("Wypisze się tyle co ma mniejsza liczba", i);
}

Jeżeli nie potrzeba, to możemy pominąć dowolną z trzech składowych pętli. Nie używasz licznika? Nie deklarujemy zmiennych. Nie potrzebujesz kończącego warunku? Nie twórz go.


let a = 10;
let i = 0;
for (; i<10 ;) {
    console.log(i);
    i++;
}

for (let j=0; j<10; ) {
    console.log(j);
    j++;
}

Tak naprawdę nic nie musimy tutaj podawać, a sama pętla może mieć postać:


for (;;) {

}

Widziałem to tylko w jednym miejscu w Internecie - w dokumentacji MDN. Pętla taka staje się nieskończoną pętlą. Na co dzień polecam jednak podawać wszystkie składowe. Czytelność i jasność kodu znacząco się powiększa.

Pętla typu while

Pętla while (dopóki) to kolejny typ pętli, który można spotkać w wielu językach. 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łaby się w nieskończoność (infinite loop), co zaowocowałoby "zawieszeniem" strony.

Pętlę while zazwyczaj stosuje się w sytuacjach, kiedy nie wiemy dokładnie, ile iteracji (powtórzeń) ma się wykonać. Wyobraź sobie, że chcesz wygenerować unikalny numer ID albo jakąś liczbę. Generujesz więc daną rzecz, następnie sprawdzasz czy wynik pasuje do założeń. Jak nie pasuje, generujesz dalej. I tak do skutku aż trafisz.


let i = 0;

while (i < 0.5) {
    console.log(i);
    i = Math.random();
}

console.log(i);

Istnieje też nieco inny wariant pętli while:


let i = 0;

do {
   i++;
   console.log(i);
} while (i < 5); //wykona się minimum 1 raz

let i = 0;

do {
    i++;
    console.log(i);
} while (false); //warunek od początku nie spełniony ale i tak 1 raz się wykona

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.

W powyższych przykładach wykonywaliśmy najczęściej tylko jedno console.log(). Takich linii kodu, które mają się powtarzać, 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.

pętle

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

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

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

Działanie powyższego skryptu ma postać:

Pętla w pętli

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.

Ważne by pętle wewnętrzne miały inny licznik niż główna pętla.
W przypadku stosowania zmiennych var użycie takiego samego licznika praktycznie zawsze oznacza zawieszenie strony.
W przypadku let można użyć licznik o takiej samej nazwie, ale tracimy wtedy dodatkowe możliwości:


for (let i=0; i<10; i++) {
    for (let j=0; j<6; j++) {
        console.log(`Główna pętla: ${i}, pętla zagnieżdżona: ${j}`)
    }
}

for (let i=0; i<10; i++) {
    for (let i=0; i<6; i++) {
        //nie mam dostępu do zewnętrznego licznika...
        console.log(`Pętla zagnieżdżona: ${i}`);
    }
}

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

Break i continue

Aby przerwać wykonywanie pętli, użyjemy instrukcji break.


let str = '';
let i = 0;

while (i <= 100) {
    str += i;
    if (str.length > 20) break;
    i++;
}

console.log(str);

const tab = ["Ala", "Monika", "Beata", "Karol"];

let userExist = false;

for (let i=0; i<tab.length; i++) {
    if (tab[i] === "Beata") {
        userExist = true;
        break; //dalej nie ma sensu sprawdzać
    }
}

//to samo uzyskamy o wiele lepiej za pomocą includes(), indexOf() czy findIndex()

let nr = -1;

for (let i=0; i<1000; i++) {
    nr = Math.random();
    if (nr >= 0.95) break;
}

console.log(nr);

Drugą instrukcją jest continue. Nie przerywa ona działania pętli, a powoduje przerwanie danej interacji i przejście do kolejnej:


const tab = ["Ala", "Monika", "Beata", "Karol", "Alicja"];

for (let i=0; i<tab.length; i++) {
    if (tab[i] === "Karol") {
        continue; //Karola pomiń
    }
    console.log(tab[i]);
}

let i = 0;
let sum = 0;

while (i < 5) {
    i++;
    if (i === 3) continue;
    sum += i;
    console.log(i, `suma kolejnych liczb to ${sum}`);
}

Trening czyni mistrza

Jeżeli chcesz sobie potrenować zdobytą wiedzę, zadania znajdują się w repozytorium pod adresem: https://github.com/kartofelek007/zadania

Wszelkie prawa zastrzeżone. Jeżeli chcesz używać jakiejś części tego kursu, skontaktuj się z autorem.
Aha - i ta strona korzysta z ciasteczek.
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.