Tablice
Jedna zmienna na jedną ocenę wystarczy do trzeciej lekcji. Przy trzydziestu ocenach potrzebujesz tablicy — struktury, która trzyma wiele wartości pod jedną nazwą i pozwala je przeglądać w pętli.
Czego się dziś nauczysz
- Zadeklarujesz tablicę o określonym typie elementów i wypełnisz ją danymi
- Dodasz i usuniesz elementy z początku, końca i środka tablicy
- Sprawdzisz, czy tablica zawiera daną wartość, i znajdziesz jej pozycję
- Przejdziesz przez wszystkie elementy pętlą
for…of - Zamienisz tekst na tablicę i tablicę na tekst
Tworzenie tablicy
Tablica to ponumerowana lista elementów. W number[] każdy element ma być liczbą. Typ elementu może również być unią, więc TypeScript pozwala też opisać tablice mieszane.
const oceny: number[] = [5, 4, 3, 5, 4];
const uczniowie: string[] = ["Ala", "Bartek", "Cezary"];
const obecnosci: boolean[] = [true, true, false, true];
// typ można pominąć — kompilator wywnioskuje go z zawartości
const punkty = [12, 8, 20]; // number[]
const przedmioty = ["INF.04", "matematyka"]; // string[]
// pusta tablica MUSI mieć podany typ
const wyniki: number[] = []; // dobrze
const cos = []; // any[] — kompilator nie ma czego się chwycić
Drugi sposób zapisu
Spotkasz też zapis Array<number> — znaczy dokładnie to samo co
number[]. W praktyce częściej używa się krótszej formy; ta druga przyda się
przy generykach w lekcji 22.
Tablica zadeklarowana jako const nie może zostać podmieniona na inną tablicę,
ale jej zawartość wolno zmieniać:
const lista = [1, 2, 3];
lista.push(4); // OK — modyfikujemy zawartość
lista[0] = 99; // OK
console.log(lista); // [99, 2, 3, 4]
lista = [5, 6]; // Błąd TS2588 — to już podmiana całej tablicy
Dostęp do elementów
const oceny = [ 5 , 4 , 3 , 5 , 4 ];
│ │ │ │ │
indeks: 0 1 2 3 4
└── oceny.length - 1
oceny.length = 5
const oceny = [5, 4, 3, 5, 4];
console.log(oceny[0]); // 5 — pierwszy element
console.log(oceny[2]); // 3
console.log(oceny.length); // 5 — liczba elementów
console.log(oceny[oceny.length - 1]); // 4 — ostatni element
console.log(oceny.at(-1)); // 4 — krócej, to samo
oceny[1] = 6; // podmiana elementu
console.log(oceny); // [5, 6, 3, 5, 4]
console.log(oceny[10]); // undefined — poza zakresem!
Poza zakresem nie ma wyjątku
W C# odwołanie poza tablicę kończy się wyjątkiem. Tutaj dostaniesz po prostu
undefined, a program pobiegnie dalej z pustą wartością, która zepsuje obliczenia
gdzieś zupełnie indziej. Zawsze pilnuj, żeby indeks mieścił się w przedziale
od 0 do length - 1.
Dodawanie i usuwanie elementów
const kolejka: string[] = ["Ala", "Bartek"];
kolejka.push("Cezary"); // na koniec → ["Ala","Bartek","Cezary"]
kolejka.unshift("Zofia"); // na początek → ["Zofia","Ala","Bartek","Cezary"]
const ostatni = kolejka.pop(); // usuwa z końca i zwraca → "Cezary"
const pierwszy = kolejka.shift(); // usuwa z początku i zwraca → "Zofia"
console.log(kolejka); // ["Ala", "Bartek"]
console.log(`Obsłużono: ${pierwszy}, odesłano: ${ostatni}`);
Usuwanie ze środka — splice
const lista = ["a", "b", "c", "d", "e"];
lista.splice(1, 2); // od pozycji 1 usuń 2 elementy
console.log(lista); // ["a", "d", "e"]
lista.splice(1, 0, "X", "Y"); // od pozycji 1 usuń 0, wstaw X i Y
console.log(lista); // ["a", "X", "Y", "d", "e"]
| Metoda | Działanie | Zwraca |
|---|---|---|
push(x) | dodaje na koniec | nową długość tablicy |
pop() | usuwa ostatni | usunięty element |
unshift(x) | dodaje na początek | nową długość tablicy |
shift() | usuwa pierwszy | usunięty element |
splice(od, ile, …) | usuwa i/lub wstawia w środku | tablicę usuniętych |
Skojarzenie, które ułatwia zapamiętanie
push i pop pracują na końcu tablicy — to zachowanie stosu
(ostatni wchodzi, pierwszy wychodzi). push i shift razem dają
kolejkę (pierwszy wchodzi, pierwszy wychodzi) — dokładnie jak kolejka do sklepiku.
Szukanie i sprawdzanie
const przedmioty = ["INF.03", "INF.04", "matematyka", "angielski"];
console.log(przedmioty.includes("INF.04")); // true
console.log(przedmioty.indexOf("matematyka")); // 2
console.log(przedmioty.indexOf("chemia")); // -1 — nie ma
// wycinek — nie zmienia oryginału
console.log(przedmioty.slice(0, 2)); // ["INF.03", "INF.04"]
console.log(przedmioty.slice(-2)); // ["matematyka", "angielski"]
// łączenie i odwracanie
const wiecej = przedmioty.concat(["fizyka"]);
console.log(wiecej.length); // 5
console.log([...przedmioty].reverse()); // kopia w odwrotnej kolejności
Uwaga: reverse i sort zmieniają oryginał
W przeciwieństwie do tekstu, tablice są modyfikowalne — reverse()
i sort() przestawiają elementy w istniejącej tablicy i zwracają ją samą.
Zapis [...tablica] tworzy kopię, na której możesz działać bez psucia oryginału.
Sortowanie
const imiona = ["Zofia", "Ala", "Bartek"];
imiona.sort();
console.log(imiona); // ["Ala", "Bartek", "Zofia"] — alfabetycznie
const liczby = [10, 9, 100, 2];
liczby.sort();
console.log(liczby); // [10, 100, 2, 9] ← to nie pomyłka!
liczby.sort((a, b) => a - b);
console.log(liczby); // [2, 9, 10, 100] — poprawnie
Domyślnie sort() porównuje elementy jak tekst — dlatego "100" trafia
przed "2". Przy liczbach trzeba podać sposób porównywania:
(a, b) => a - b dla rosnąco, (a, b) => b - a dla malejąco.
Zapis ze strzałką poznasz dokładnie w lekcji 13 — na razie potraktuj go jak gotowy wzorzec.
Przeglądanie tablicy
Najczytelniejszy sposób to pętla for…of, która sama pobiera kolejne elementy:
const oceny = [5, 4, 3, 5, 4];
// wariant 1 — for…of: gdy potrzebujesz tylko wartości
let suma = 0;
for (const ocena of oceny) {
suma += ocena;
}
console.log(`Suma: ${suma}, średnia: ${(suma / oceny.length).toFixed(2)}`);
// wariant 2 — klasyczna pętla for: gdy potrzebujesz też numeru pozycji
for (let i = 0; i < oceny.length; i++) {
console.log(`${i + 1}. ocena: ${oceny[i]}`);
}
// wariant 3 — forEach: numer dostajesz jako drugi argument
oceny.forEach((ocena, indeks) => {
console.log(`[${indeks}] = ${ocena}`);
});
Suma: 21, średnia: 4.20
1. ocena: 5
2. ocena: 4
3. ocena: 3
4. ocena: 5
5. ocena: 4
[0] = 5
[1] = 4
[2] = 3
[3] = 5
[4] = 4
Nie myl for…of z for…in
for (const x of tablica) daje wartości.
for (const x in tablica) daje indeksy jako tekst — dla tablic
praktycznie nigdy nie jest tym, czego chcesz. Zapamiętaj: of jak obiekty w środku.
Tablica a tekst
Dwie metody, które będziesz stosować w każdym projekcie przetwarzającym dane:
// tekst → tablica
const csv = "Ala;Bartek;Cezary;Dorota";
const imiona = csv.split(";");
console.log(imiona); // ["Ala","Bartek","Cezary","Dorota"]
console.log(imiona.length); // 4
const zdanie = "programowanie jest fajne";
console.log(zdanie.split(" ")); // podział na słowa
console.log("abc".split("")); // ["a","b","c"] — na pojedyncze znaki
// tablica → tekst
const przedmioty = ["INF.03", "INF.04"];
console.log(przedmioty.join(", ")); // "INF.03, INF.04"
console.log(przedmioty.join(" | ")); // "INF.03 | INF.04"
console.log(przedmioty.join("")); // "INF.03INF.04"
split i join wystarczają do naszego prostego formatu rozdzielanego separatorem. Pełny CSV dopuszcza cytowane pola i separatory wewnątrz nich, dlatego do ogólnego CSV potrzebny jest parser obsługujący jego reguły.
Dziennik ocen
Program wczytuje oceny zapisane w jednym wierszu (tak jak przyszłyby z pliku), liczy statystyki i rysuje wykres słupkowy w konsoli.
// ── dane, tak jak przyszłyby z pliku CSV ──
const wiersz = "5;4;3;5;2;4;5;3;4;6";
const uczen = "Marta Kowalska";
// ── 1. Zamiana tekstu na tablicę liczb ──
const teksty: string[] = wiersz.split(";");
const oceny: number[] = [];
for (const t of teksty) {
oceny.push(Number(t));
}
// ── 2. Podstawowe statystyki ──
let suma = 0;
let najwyzsza = oceny[0];
let najnizsza = oceny[0];
for (const ocena of oceny) {
suma += ocena;
if (ocena > najwyzsza) najwyzsza = ocena;
if (ocena < najnizsza) najnizsza = ocena;
}
const srednia = suma / oceny.length;
const liczbaJedynek = oceny.filter(o => o === 1).length;
const zagrozenie = srednia < 2.0;
// ── 3. Raport ──
console.log("═".repeat(42));
console.log(`DZIENNIK — ${uczen}`);
console.log("═".repeat(42));
console.log(`Oceny: ${oceny.join(", ")}`);
console.log(`Liczba: ${oceny.length}`);
console.log(`Średnia: ${srednia.toFixed(2)}`);
console.log(`Najwyższa: ${najwyzsza} Najniższa: ${najnizsza}`);
console.log(`Jedynki: ${liczbaJedynek}`);
console.log(`Zagrożenie: ${zagrozenie ? "TAK" : "nie"}`);
console.log("─".repeat(42));
// ── 4. Wykres słupkowy: ile razy wystąpiła każda ocena ──
const licznik = [0, 0, 0, 0, 0, 0, 0]; // indeksy 1–6, zero nieużywane
for (const ocena of oceny) {
licznik[ocena] = licznik[ocena] + 1;
}
for (let stopien = 1; stopien <= 6; stopien++) {
const ile = licznik[stopien];
console.log(`${stopien} │ ${"█".repeat(ile)} ${ile > 0 ? ile : ""}`);
}
══════════════════════════════════════════
DZIENNIK — Marta Kowalska
══════════════════════════════════════════
Oceny: 5, 4, 3, 5, 2, 4, 5, 3, 4, 6
Liczba: 10
Średnia: 4.10
Najwyższa: 6 Najniższa: 2
Jedynki: 0
Zagrożenie: nie
──────────────────────────────────────────
1 │
2 │ █ 1
3 │ ██ 2
4 │ ███ 3
5 │ ███ 3
6 │ █ 1
Trzy techniki warte zapamiętania
| Technika | Na czym polega |
|---|---|
| Budowanie tablicy w pętli | Zaczynamy od pustej const oceny: number[] = [] i dokładamy elementy przez
push. To najczęstszy wzorzec przetwarzania danych wejściowych. |
| Szukanie minimum i maksimum | Zmienne startują od pierwszego elementu, nie od zera. Gdyby
najnizsza zaczynała od 0, żadna ocena nigdy nie byłaby od niej mniejsza. |
| Tablica jako licznik | licznik[ocena]++ zlicza wystąpienia bez żadnego if: numer indeksu
jest zliczaną wartością. Ta sztuczka pojawia się w wielu zadaniach z sortowania
i statystyki. |
Co to za filter
oceny.filter(o => o === 1).length zlicza jedynki jedną linijką — tworzy tablicę
tylko z pasujących elementów i mierzy jej długość. Cała rodzina takich metod
(map, filter, reduce) czeka na nas w lekcji 23.
Na razie wystarczy, że rozpoznajesz zapis.
Na co uważać
| Kod | Problem |
|---|---|
for (let i = 0; i <= t.length; i++) |
Klasyk. Ostatni obieg sięga poza tablicę i daje undefined.
Ma być i < t.length. |
const oceny = []; |
Przy pustej tablicy podaj typ, np. const oceny: number[] = [];. Bez niego wynik wnioskowania zależy od kontekstu i może być mniej czytelny. |
[10, 9, 100].sort() |
Sortowanie jak tekst. Przy liczbach podaj (a, b) => a - b. |
const kopia = oryginal; |
To nie jest kopia — obie nazwy wskazują tę samą tablicę, więc zmiana w jednej
widoczna jest w drugiej. Kopię robi [...oryginal]. |
tablica.length() |
length to właściwość — bez nawiasów. |
oceny.push("5") |
Do number[] nie wolno wstawić tekstu. Błąd TS2345 —
i bardzo dobrze, bo to on chroni przed pomyłką z lekcji 1. |
Pętla na zapas
Do przejścia przez tablicę potrzebna jest pętla, więc poznajesz ją tutaj w najprostszej postaci — for…of bierze kolejne elementy i nie wymaga liczenia indeksów. Wszystkie rodzaje pętli, sterowanie ich przebiegiem przez break i continue oraz pętle zagnieżdżone omawia lekcja 10. Zadania z tej lekcji wymagają wyłącznie tego, co widzisz wyżej.
Zadania
const t = [3, 1, 4, 1, 5];
console.log(t.length);
console.log(t[1]);
console.log(t.indexOf(1));
console.log(t.includes(9));
t.push(9);
console.log(t.pop());
console.log(t.slice(1, 3));
console.log(t.join("-"));
pokaż rozwiązanie
5
1
1 indexOf zwraca pozycję PIERWSZEGO wystąpienia
false
9 pop zwraca to, co właśnie dodaliśmy
[1, 4] slice(1,3) bierze indeksy 1 i 2
3-1-4-1-5
Utwórz tablicę z imionami sześciu uczniów. Wypisz ją w postaci ponumerowanej listy
(1. Ala, 2. Bartek…), a pod nią podaj liczbę uczniów oraz imię
pierwsze i ostatnie alfabetycznie.
pokaż rozwiązanie
const uczniowie = ["Zofia", "Ala", "Bartek", "Dorota", "Cezary", "Ewa"];
for (let i = 0; i < uczniowie.length; i++) {
console.log(`${i + 1}. ${uczniowie[i]}`);
}
const posortowani = [...uczniowie].sort();
console.log(`Razem: ${uczniowie.length}`);
console.log(`Pierwszy alfabetycznie: ${posortowani[0]}`);
console.log(`Ostatni alfabetycznie: ${posortowani.at(-1)}`);
Zwróć uwagę na [...uczniowie] — sortujemy kopię, żeby oryginalna kolejność
listy obecności została nienaruszona.
Mając tablicę temperatur z siedmiu dni (mogą być ujemne), policz i wypisz: średnią, wartość najwyższą i najniższą, liczbę dni z mrozem oraz numery dni cieplejszych niż średnia.
pokaż rozwiązanie
const temperatury = [-3, 0, 2, -5, 1, 4, -1];
const dni = ["pon", "wt", "śr", "czw", "pt", "sob", "niedz"];
let suma = 0;
let maks = temperatury[0];
let min = temperatury[0];
let mrozne = 0;
for (const t of temperatury) {
suma += t;
if (t > maks) maks = t;
if (t < min) min = t;
if (t < 0) mrozne++;
}
const srednia = suma / temperatury.length;
console.log(`Średnia: ${srednia.toFixed(1)}°C`);
console.log(`Maksimum: ${maks}°C, minimum: ${min}°C`);
console.log(`Dni z mrozem: ${mrozne}`);
for (let i = 0; i < temperatury.length; i++) {
if (temperatury[i] > srednia) {
console.log(`Powyżej średniej: ${dni[i]} (${temperatury[i]}°C)`);
}
}
Dwie tablice o tej samej długości, przeglądane wspólnym indeksem — to bardzo częsty wzorzec. Wygodniejszy sposób (jedna tablica obiektów) poznasz w lekcji 14.
Zasymuluj kolejkę: zacznij od trzech osób, dopisz dwie kolejne na koniec, obsłuż dwie pierwsze (usuń je z początku i wypisz komunikat), a jednej osobie pozwól wejść na sam początek jako nauczycielowi. Po każdej operacji wypisuj aktualny stan kolejki i jej długość.
Wyniki egzaminu przyszły jako jeden tekst: "Ala:78;Bartek:45;Cezary:92;Dorota:31;Ewa:60".
Rozbij go na dane, a następnie wypisz tabelkę: imię (wyrównane do 10 znaków), wynik, pasek
z gwiazdek (jedna gwiazdka na 10 punktów) oraz status zdania (próg 50%). Na końcu podaj średnią
i zdawalność w procentach.
pokaż rozwiązanie
const dane = "Ala:78;Bartek:45;Cezary:92;Dorota:31;Ewa:60";
const PROG = 50;
const rekordy = dane.split(";");
const imiona: string[] = [];
const wyniki: number[] = [];
for (const rekord of rekordy) {
const czesci = rekord.split(":");
imiona.push(czesci[0]);
wyniki.push(Number(czesci[1]));
}
let suma = 0;
let zdalo = 0;
console.log("IMIĘ".padEnd(10) + "WYNIK WYKRES");
console.log("─".repeat(34));
for (let i = 0; i < imiona.length; i++) {
const w = wyniki[i];
const pasek = "*".repeat(Math.floor(w / 10));
const status = w >= PROG ? "zdał" : "nie zdał";
console.log(imiona[i].padEnd(10) + String(w).padStart(3) + "% " + pasek.padEnd(10) + status);
suma += w;
if (w >= PROG) zdalo++;
}
console.log("─".repeat(34));
console.log(`Średnia: ${(suma / wyniki.length).toFixed(1)}%`);
console.log(`Zdawalność: ${((zdalo / wyniki.length) * 100).toFixed(0)}%`);
Rozbijamy nasz umowny tekst najpierw na rekordy, potem na pola. To nie jest uniwersalny parser CSV — działa, ponieważ w tym zadaniu imiona i wyniki nie zawierają separatorów.
Co trzeba zapamiętać
- Typ tablicy to typ elementów plus
[]:number[],string[]. - Pustej tablicy nadawaj czytelny typ, np. number[]. Bez kontekstu jej wnioskowanie może zależeć od miejsca i opcji kompilatora (np. any[] lub never[]).
- Indeksy idą od
0dolength - 1; poza zakresem dostanieszundefined. push/popobsługują koniec,unshift/shiftpoczątek,spliceśrodek.sort()ireverse()zmieniają oryginał — kopiuj przez[...tablica].splitzamienia tekst na tablicę,jointablicę na tekst.for…ofdaje wartości i to jego używaj domyślnie.