Oceny całej klasy, lista produktów w koszyku, temperatury z każdego dnia miesiąca: takie dane przechowujemy w tablicach, a przetwarzamy pętlą. To połączenie pojawia się w prawie każdym zadaniu z JavaScriptu na INF.03. Każdy kod możesz uruchomić przyciskiem Uruchom albo skrótem Ctrl+Enter.
Wyobraź sobie, że masz zapisać oceny 30 uczniów. Bez tablicy potrzebujesz 30 osobnych zmiennych i 30 linijek, żeby je zsumować. Tablica mieści wszystkie wartości w jednej zmiennej, a pętla przejdzie po nich bez względu na to, czy jest ich 3, czy 3000.
Tablica działa jak szafka z ponumerowanymi przegródkami. W każdej przegródce leży jedna wartość, a numer przegródki to indeks. Numerację zaczynamy od zera.
let nazwa = [wartość, wartość, wartość];
Nawiasy kwadratowe [ ], elementy oddzielone przecinkami. Pusta tablica to [].
Do konkretnego elementu dostajesz się, podając indeks w nawiasach kwadratowych: tablica[indeks]. Właściwość length mówi, ile elementów ma tablica.
| Zapis | Co robi | Dla owoce = ["jabłko", "gruszka", "śliwka"] |
|---|---|---|
| owoce[0] | pierwszy element | "jabłko" |
| owoce.length | liczba elementów | 3 |
| owoce[owoce.length - 1] | ostatni element | "śliwka" |
| owoce[1] = "kiwi" | zmienia element pod indeksem 1 | ["jabłko", "kiwi", "śliwka"] |
| owoce[5] | indeks spoza tablicy | undefined |
Pierwszy to [0], ostatni to [length − 1]. Elementów jest length, ale indeksu [length] już nie ma.
Ciekawostka: tablicę zadeklarowaną przez const też można zmieniać (owoce[1] = "kiwi" zadziała). const zabrania tylko przypisania zupełnie nowej tablicy do tej samej zmiennej.
Tablica dni ma 7 elementów. Jak odczytać ostatni?
Indeksy to 0, 1, …, 6, więc ostatni to dni[6], czyli dni[dni.length - 1]. dni[7] zwróci undefined. Sam zapis dni[length] to błąd, bo trzeba napisać dni.length.
Tablica ma wbudowane metody, czyli gotowe polecenia wywoływane po kropce. Wypróbuj je na tablicy poniżej i obserwuj, jak zmieniają się przegródki i indeksy:
owoce| Metoda | Co robi | Co zwraca |
|---|---|---|
| push(x) | dodaje x na koniec | nową długość |
| pop() | usuwa ostatni element | usunięty element |
| unshift(x) | dodaje x na początek; pozostałe indeksy przesuwają się o 1 | nową długość |
| shift() | usuwa pierwszy element | usunięty element |
| indexOf(x) | szuka x | indeks pierwszego wystąpienia albo -1, gdy nie ma |
| includes(x) | sprawdza, czy x jest w tablicy | true / false |
| join(", ") | skleja elementy w jeden tekst z podanym separatorem | tekst |
push / pop działają na końcu, jak dokładanie i zdejmowanie talerzy ze stosu. unshift / shift działają na początku, jak kolejka do sklepiku.
Najczęściej użyjesz push: tak buduje się nową tablicę w pętli.
Co zwróci ["a", "b", "c"].indexOf("x")?
-1 to umowny sygnał „nie znaleziono”. Wartość 0 oznaczałaby, że x jest pierwszym elementem, dlatego sprawdzamy if (tab.indexOf(x) !== -1) albo prościej if (tab.includes(x)).
Licznik pętli i przechodzi po kolejnych indeksach: 0, 1, 2… aż do ostatniego. W każdym obiegu tablica[i] to bieżący element.
for (let i = 0; i < tablica.length; i++) {
// tablica[i] to bieżący element
}
Od 0, do < length, krok i++. Start od 0, bo pierwszy indeks to 0. Warunek <, a nie <=, bo ostatni indeks to length − 1.
let owoce = ["jabłko", "gruszka", "śliwka"];
for (let i = 0; i < owoce.length; i++) {
console.log(owoce[i]);
}
Pętla może też iść od końca: startujesz od ostatniego indeksu i zmniejszasz licznik.
Co wypisze ostatni obieg tej pętli?
let t = [10, 20, 30];
for (let i = 0; i <= t.length; i++) {
console.log(t[i]);
}
Przy <= pętla wykona się także dla i = 3, a t[3] nie istnieje, więc wypisze undefined. JavaScript nie zgłosi błędu, dlatego taką pomyłkę łatwo przeoczyć.
Gdy interesują Cię tylko wartości, a nie ich numery, możesz użyć krótszej pętli for…of. W każdym obiegu zmienna dostaje kolejny element tablicy.
for (const element of tablica) {
// element to bieżąca wartość
}
Czytaj to tak: „dla każdego elementu z tablicy”.
| Pętla | Wybierz, gdy |
|---|---|
| for (let i = 0; …) | potrzebujesz numeru elementu, chcesz zmieniać tablicę, iść od końca albo korzystać z dwóch tablic naraz (ten sam i) |
| for (const x of tab) | tylko odczytujesz kolejne wartości, np. sumujesz albo wypisujesz |
Prawie każde zadanie z tablicą to jeden z tych schematów albo ich połączenie.
let suma = 0;
for (let i = 0; i < tab.length; i++) {
suma += tab[i];
}
let srednia = suma / tab.length;
Zaczynasz od założenia, że pierwszy element jest największy. Potem porównujesz z nim każdy kolejny, a gdy trafisz na większy, zapamiętujesz go.
let max = t[0];
for (let i = 1; i < t.length; i++) {
if (t[i] > max) {
max = t[i];
}
}
Gdy znajdziesz element, zapamiętaj jego indeks i przerwij pętlę słowem break. Wartość -1 na starcie oznacza „jeszcze nie znaleziono”.
Często dane są w dwóch tablicach: w jednej nazwy, w drugiej ceny. Element o indeksie 0 w jednej tablicy pasuje do elementu o indeksie 0 w drugiej. Wtedy potrzebujesz klasycznej pętli for z licznikiem i.
Na egzaminie wynik często trafia na stronę jako lista albo tabela. W pętli sklejasz tekst z kodem HTML, a potem wstawiasz go na stronę. Samo wstawianie (innerHTML) poznasz na kolejnych lekcjach.
| Błąd | Objaw | Poprawka |
|---|---|---|
| i <= tab.length | ostatni obieg wypisuje undefined | i < tab.length |
| let i = 1 | pierwszy element jest pomijany | zaczynaj od 0 |
| tab.length() | TypeError: … is not a function | length bez nawiasów: tab.length |
| tab(0) | TypeError: tab is not a function | nawiasy kwadratowe: tab[0] |
| tab[tab.length] | undefined zamiast ostatniego | tab[tab.length - 1] |
| let suma = 0 w pętli | suma zeruje się w każdym obiegu | zmienną startową deklaruj przed pętlą |
| console.log(tab) | na stronie widać przecinki zamiast ładnej listy | tab.join(", ") albo pętla |
Kliknij Sprawdź. Sprawdzarka podmieni zawartość tablic z pierwszych linijek na inne dane i porówna, co wypisuje Twój program. Kod musi więc działać dla dowolnej tablicy: używaj length i pętli, a nie konkretnych liczb. Komunikaty wypisuj dokładnie w podanej postaci.
Wypisz w dwóch liniach Suma: 20 oraz Średnia: 4 dla ocen z tablicy oceny.
let oceny = [5, 3, 4, 6, 2];
let suma = 0;
for (let i = 0; i < oceny.length; i++) {
suma += oceny[i];
}
console.log("Suma: " + suma);
console.log("Średnia: " + suma / oceny.length);
Dla tablicy temperatury wypisz Max: 18 i Min: -3. Uwaga: sprawdzarka przetestuje też tablicę z samymi ujemnymi temperaturami.
let temperatury = [12, -3, 18, 7, 15];
let max = temperatury[0];
let min = temperatury[0];
for (let i = 1; i < temperatury.length; i++) {
if (temperatury[i] > max) max = temperatury[i];
if (temperatury[i] < min) min = temperatury[i];
}
console.log("Max: " + max);
console.log("Min: " + min);
Tablica wyniki zawiera punkty z egzaminu. Zdaje się od 50 punktów. Wypisz Zdało: 3 z 5 (z odpowiednimi liczbami).
let wyniki = [45, 78, 50, 32, 91];
let zdalo = 0;
for (const w of wyniki) {
if (w >= 50) {
zdalo++;
}
}
console.log("Zdało: " + zdalo + " z " + wyniki.length);
Znajdź w tablicy uczniowie imię zapisane w zmiennej szukany. Jeśli jest, wypisz Kasia: indeks 2. Jeśli nie ma, wypisz Nie znaleziono: Kasia.
let uczniowie = ["Ania", "Bartek", "Kasia", "Damian"];
let szukany = "Kasia";
let pozycja = -1;
for (let i = 0; i < uczniowie.length; i++) {
if (uczniowie[i] === szukany) {
pozycja = i;
break;
}
}
if (pozycja !== -1) {
console.log(szukany + ": indeks " + pozycja);
} else {
console.log("Nie znaleziono: " + szukany);
}
// krócej: let pozycja = uczniowie.indexOf(szukany);
Utwórz nową tablicę z liczbami parzystymi z tablicy liczby i wypisz Parzyste: 4, 8, 2. Jeśli nie ma żadnej liczby parzystej, wypisz Brak liczb parzystych.
let liczby = [3, 4, 7, 8, 2, 9];
let parzyste = [];
for (const n of liczby) {
if (n % 2 === 0) {
parzyste.push(n);
}
}
if (parzyste.length > 0) {
console.log("Parzyste: " + parzyste.join(", "));
} else {
console.log("Brak liczb parzystych");
}
Tablice produkty i ceny mają tę samą długość. Dla każdego produktu wypisz linię chleb: 4 zł, a na końcu Razem: 15.5 zł.
let produkty = ["chleb", "mleko", "masło"];
let ceny = [4, 3.5, 8];
let razem = 0;
for (let i = 0; i < produkty.length; i++) {
console.log(produkty[i] + ": " + ceny[i] + " zł");
razem += ceny[i];
}
console.log("Razem: " + razem + " zł");
Z tablicy imiona zbuduj w jednej zmiennej kod listy HTML i wypisz go w jednej linii, np. <ul><li>Ania</li><li>Bartek</li></ul>. Dla pustej tablicy wynik to <ul></ul>.
let imiona = ["Ania", "Bartek"];
let html = "<ul>";
for (const imie of imiona) {
html += "<li>" + imie + "</li>";
}
html += "</ul>";
console.log(html);
let t = [5, 3, 4]; t[0] // pierwszy t[t.length - 1] // ostatni t[1] = 7; // zmiana
Indeksy od 0. Ostatni to length − 1.
t.push(x) t.pop()
t.unshift(x) t.shift()
t.indexOf(x) t.includes(x)
t.join(", ")push/pop na końcu, unshift/shift na początku. indexOf zwraca -1, gdy nie znajdzie.
for (let i = 0; i < t.length; i++) {
t[i]
}Od 0, do < length, krok i++.
for (const x of t) {
x
}Gdy potrzebujesz tylko wartości, bez indeksu.
let suma = 0, max = t[0];
for (const x of t) {
suma += x;
if (x > max) max = x;
}
suma / t.lengthmax zaczynaj od t[0], a nie od 0.
let wynik = [];
for (const x of t) {
if (warunek) wynik.push(x);
}
let poz = t.indexOf(szukany);Nowa pusta tablica + push w pętli.
Na następnej lekcji: funkcje, czyli jak zamknąć kod w nazwanym bloku i używać go wiele razy.