Kontynuujemy naukę języka JavaScript. Zostaniemy jeszcze chwilę przy tablicach, które musimy lepiej poznać. Nauczymy się dodawać i usuwać elementy z tablicy, sprawdzać czy element w tablicy występuje i tym podobne.
Jak zwykle, podaję templatkę dla pliku HTML, w którym będziemy pisać nasz kod JavaScript:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>Welcome to my website</h1>
<script>
let names = ["Jim", "John", "Bob", "Jane"];
//nasz kod tutaj
</script>
</body>
</html>
Sprawdź, czy element istnieje – indexOf, lastIndexOf, includes
Aby sprawdzić, czy dany element istnieje w tablicy, możemy użyć funkcji includes:
<script>
let names = ["Jim", "John", "Bob", "Jane"];
console.log(names.includes("Jim"));
//true
</script>
Jeżeli chcemy sprawdzić, czy dany element istnieje i zwrócić jego indeks, używamy funkcji indexOf:
<script>
let names = ["Jim", "John", "Bob", "Jane"];
let idx = names.indexOf("Jim");
if(idx !== -1)
console.log(idx);
//0
</script>
„Jim” znajduje się pod indeksem 0. Sprawdzamy, czy indeks nie równa się -1, ponieważ indeks -1 to wartość, którą indexOf zwraca, gdy nie znajdzie naszego elementu w tablicy:
<script>
let names = ["Jim", "John", "Bob", "Jane"];
let idx = names.indexOf("James");
if(idx === -1)
console.log("James not present in our array");
//James not present in our array
</script>
Warto zauważyć, że funkcja indexOf działa od lewej do prawej i zwraca wartość indeksu pierwszego znalezionego elementu. W tablicy mogą być duplikaty i jeżeli chcemy szukać od prawej, mamy do tego funkcję lastIndexOf:
<script>
let names = ["Jim", "John", "Bob", "Jane", "Jim"];
let first_idx = names.indexOf("Jim");
let last_idx = names.lastIndexOf("Jim");
if(first_idx !== -1 && last_idx !== -1){
console.log(first_idx);
console.log(last_idx);
}
//0
//4
</script>
Mamy tutaj warunek z użyciem operatora „&&” czyli „i”. Obie strony warunku muszą być prawdziwe, to jest first_idx różny od -1 oraz last_idx różny od -1.
Jak widać indexOf podaje indeks pierwszego elementu szukając od lewej, lastIndexOf – szukając od prawej.
Dodawanie elementów – push
Metoda push pozwala na dodawanie elementów na samym końcu listy. Istnieją też metody do dodawania elementów na początku listy lub w dowolnym jej miejscu, ale dla spokoju na razie nie będziemy się w nie zagłębiać.
let names = ["Jim", "John", "Bob"];
names.push("Jane");
console.log(names);
//['Jim', 'John', 'Bob', 'Jane']
Jak widać „Jane” zostało dodane na końcu naszej listy.
Usuwanie elementów – pop
Istnieją metody na usuwanie elementów z różnych miejsc listy – początku bądź środka – ale na razie nie będziemy się w nie zagłębiać, aby nie przytłoczyć się ilością metod do zapamiętania.
Elementy najczęściej usuwamy „z końca” listy i służy do tego metoda pop, która usuwa element na samym końcu a także go zwraca:
<script>
let names = ["Jim", "John", "Bob"];
let last_name = names.pop()
console.log(last_name);
//Bob
console.log(names);
//['Jim', 'John']
</script>
Jak widać pop usunęło nam ostatni element i zwróciło go do zmiennej last_name.
Dekompozycja tablic – przypisywanie elementów do zmiennych
Oto nasza lista:
<script>
let names = ['Jim', 'John', 'Bob', 'Jane', "James"]
</script>
Gdybyśmy zechcieli przypisać do zmiennych wartość pierwszego, drugiego i trzeciego imienia, używając indeksów, raczej byśmy sobie poradzili:
<script>
let names = ['Jim', 'John', 'Bob', 'Jane', "James"]
let first = names[0];
let second = names[1];
let third = names[2];
</script>
Możemy jednak zrobić to prościej:
<script>
let names = ['Jim', 'John', 'Bob', 'Jane', "James"]
let [first, second, third] = names;
console.log(first, second, third);
//Jim John Bob
</script>
To się nazywa dekompozycja tablic. Możemy też pomijać pewne wartości, zróbmy na przykład zmienne dla pierwszego i trzeciego imienia, pomińmy drugie:
<script>
let names = ['Jim', 'John', 'Bob', 'Jane', "James"]
let [first, , third] = names;
console.log(first, third);
//Jim Bob
</script>
Możemy też złapać sobie pierwsze, drugie i trzecie imię do osobnych zmiennych, zaś całą resztę wrzucić do jednej tablicy, nazwijmy ją sobie „rest”:
<script>
let names = ['Jim', 'John', 'Bob', 'Jane', "James"]
let [first,second,third, ...rest] = names;
console.log(first, second, third);
//Jim John Bob
console.log(rest);
// ['Jane', 'James']
</script>
Wreszcie, ostatnią sztuczką, jaką możemy zrobić jest zamiana wartości dwóch zmiennych:
<script>
let a = 5;
let b = 10;
console.log(a, b);
//5 10
[a, b] = [b, a];
console.log(a, b);
//10 5
</script>
Zadanie 1 – sprawdź, czy element występuje 1 raz
Mamy napisać funkcję, która sprawdzi, czy element danej tablicy występuje w niej, ale tylko jeden raz.
Zróbmy to przy pomocy klasycznej pętli for:
<script>
let arr = [1,1,2,3,3,4];
function has_once(arr, target){
let cnt = 0;
for(let idx = 0; idx < arr.length; idx++){
if(arr[idx] === target)
cnt += 1;
}
return cnt === 1
}
console.log(has_once(arr, 1));
console.log(has_once(arr, 2));
console.log(has_once(arr, 3));
console.log(has_once(arr, 100));
//false
//true
//false
//false
</script>
Funkcja przyjmuje tablicę oraz to, czego szukamy. Tworzy taki licznik, ustawiony na 0. Przechodzi pętlą for po każdym elemencie tablicy i porównuje go z szukanym elementem. Licznik zwiększany za każdym razem, gdy odnaleziony zostanie element.
Zwracamy warunek, że licznik jest równy 1, czyli element występuje, ale tylko raz.
Czy da się tę funkcję zmienić, zastąpić pętlę znanymi nam includes, indexOf i lastIndexOf?
Pomyślmy.
Includes sprawdza, czy element istnieje. indexOf zwraca indeks pierwszego znalezionego elementu, szukając od lewej zaś lastIndexOf – szukając od prawej.
Jeżeli indexOf i lastIndexOf zwracają ten sam wynik, oznacza to, że element albo nie istnieje (-1) albo istnieje tylko jeden raz (pierwszy znaleziony indeks szukając od lewej i prawej jest taki sam).
Oto nasza funkcja:
<script>
let arr = [1,1,2,3,3,4];
function has_once(arr, target){
if(!arr.includes(target))
return false;
return arr.indexOf(target) === arr.lastIndexOf(target);
}
console.log(has_once(arr, 1));
console.log(has_once(arr, 2));
console.log(has_once(arr, 3));
console.log(has_once(arr, 100));
//false
//true
//false
//false
</script>
Jeżeli tablica nie zawiera szukanego elementu (operator negacji „!” czyli „nie”), zwracamy fałsz.
Jeżeli pierwszy znaleziony indeks elementu szukając od lewej i prawej jest taki sam – zwracamy prawdę. Jeżeli te indeksy się różnią, element występuje więcej niż jeden raz, dostajemy fałsz.
Zadanie 2 – wypełnij tablicę liczbami
Proste zadanie. Mamy pustą tablicę:
<script>
let arr = [];
</script>
Nasze zadanie – wrzucić do niej liczby od 1 do 10 włącznie. Zalecane podejście – użycie klasycznej pętli for oraz metody push.
Nasze rozwiązanie:
<script>
let arr = [];
for(let num = 1; num <= 10; num++)
{
arr.push(num);
}
console.log(arr);
//[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
</script>
Oczywiście metod rozwiązania zadania może być wiele. Oto jedna z możliwych z wykorzystaniem pętli while:
<script>
let arr = [];
let num = 1;
while(arr.length !== 10) {
arr.push(num++);
}
console.log(arr);
//[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
</script>
Tworzymy zmienną num równą 1. Stawiamy warunek pętli – działaj tak długo, jak długość tablicy nie będzie równa 10.
Poprzez push wrzucamy num do tablicy a następnie podnosimy je o 1. Mała sztuczka z użyciem „num++” – najpierw wrzuci num do tablicy, później podniesie o 1.
Zadanie 3 – odwróć tablicę
Mamy taką oto tablicę:
<script>
let arr = [1,2,3];
</script>
Chcemy napisać funkcję, która odwróci naszą tablicę i zwróci odwróconą. Zalecane podejście – pętla while, metody pop oraz push.
Jeżeli nie chcemy się głowić, możemy od razu przejść do rozwiązania:
<script>
function reverse_arr(arr){
let reversed = []
while(arr.length > 0)
reversed.push(arr.pop());
return reversed;
}
let arr = [1,2,3];
let reversed = reverse_arr(arr);
console.log(reversed);
//[3, 2, 1]
</script>
Funkcja reverse_arr zaczyna od przyjęcia tablicy arr i utworzenia tablicy reversed. Następnie mamy pętlę while.
Warunkiem pętli while jest to, że tablica pierwsza ma długość większą od zera.
Funkcja push dodaje wartość do tablicy (tutaj tablicy reversed) zaś pop to funkcja, która i usuwa element i jednocześnie go zwraca.
Użyliśmy sprytnego zapisu, gdzie element zostaje w jednej linijce zrzucony z tablicy arr i dodany do tablicy reversed.
Zwracamy tablicę reversed.
Myślę, że to dobry moment, aby zakończyć. Zabawy z JavaScriptem, także z tablicami, będziemy kontynuować w następnych lekcjach.