Kihagyás

Tömbök

Tömbök

JavaScriptben a tömb (Array) tetszőleges mennyiségű, nem feltétlenül azonos típusú adat tárolására alkalmas adatszerkezet.

Tömb létrehozása

JavaScriptben alapvetően többféle módszerrel hozhatunk létre tömböket:

  • a new Array() segítségével
  • a tömbelemek szögletes zárójelek közötti felsorolásával
  • az Array.from() metódussal más iterálható objektumokból (ezzel egyelőre nem foglalkozunk)
  • az Array.of() metódussal paraméterekből

A gyakorlaton szinte mindig a tömbelemek szögletes zárójelek közötti felsorolását fogjuk használni tömbök létrehozásához.

Példa: Tömb létrehozása

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
let array1 = new Array(10);           // create array with 10 empty slots
let array2 = new Array(10, 20);       // create array with elements 10 and 20

let array3 = [];                      // create empty array
let array4 = [10, 20, 30, 40];        // create array with number data
let array5 = ["apple", "pear", "plum", "peach"];  // string array

// Modern methods
let array6 = Array.from("hello");     // ["h", "e", "l", "l", "o"]
let array7 = Array.of(1, 2, 3);       // [1, 2, 3]
let array8 = Array.from({length: 5}, (_, i) => i); // [0, 1, 2, 3, 4]

Tömbök típusának ellenőrzése

A JavaScript tömbök objektumok, ezért a typeof operátor nem elegendő a típus meghatározásához:

1
2
3
4
let numbers = [1, 2, 3];
console.log(typeof numbers);        // "object" - not very helpful!
console.log(Array.isArray(numbers)); // true - this is what we need!
console.log(Array.isArray("hello")); // false

De szerencsére létezik az Array.isArray metódus, ami visszaadja a paraméterről, hogy az tömb-e.

Tömbök hossza

Egy tömb hosszának lekérdezésére a length property-t használjuk JavaScriptben (hasonló a szövegekhez).

1
2
let fruits = ["apple", "pear", "plum", "peach"];
console.log(fruits.length);

Kimenet

4

Fontos: A length property írható is! Ezt ritkán használjuk, de érdemes tudni:

1
2
3
4
5
6
let numbers = [1, 2, 3, 4, 5];
numbers.length = 3;               // truncate array
console.log(numbers);             // [1, 2, 3]

numbers.length = 5;               // extend array with undefined values
console.log(numbers);             // [1, 2, 3, undefined, undefined]

Tömbelemek indexelése

A tömbök elemeit a tömbindex operátorokkal (szögletes zárójelek) tudjuk elérni: arrayName[index].

Az indexelés itt is 0-tól kezdődik. A Pythonban létező negatív, illetve intervallumos indexelés JavaScriptben nem működik!

Ha JavaScriptben egy nem létező indexű tömbelemre hivatkozunk (pl. alul- vagy túlindexeljük a tömböt), akkor undefined értéket kapunk.

1
2
3
4
5
6
let cats = ["Garfield", "Nermal", "Grumpy Cat", "Tom"];

console.log(cats[0]);                    // first element
console.log(cats[cats.length - 1]);      // last element
console.log(cats[-1]);                   // this doesn't work in JavaScript!
console.log(cats[10]);                   // undefined - out of bounds

Kimenet

Garfield

Tom

undefined

undefined

A stringekkel ellentétben a tömb egy mutable (módosítható) típus, így lehetőségünk van arra, hogy egy adott indexű elem értékét módosítsuk.

1
2
3
let cats = ["Garfield", "Nermal", "Grumpy Cat", "Tom"];
cats[1] = "Sylvester";
console.log(cats);

Kimenet

[ 'Garfield', 'Sylvester', 'Grumpy Cat', 'Tom' ]

Destructuring assignment

Modern JavaScriptben elegánsan ki tudunk bontani tömbelemeket változókba:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
let colors = ["red", "green", "blue"];

// Traditional way
let firstColor = colors[0];
let secondColor = colors[1];
let thirdColor = colors[2];

// Modern destructuring way
let [first, second, third] = colors;
console.log(first);   // "red"
console.log(second);  // "green"
console.log(third);   // "blue"

Ez a destruktúráló értékadás, amikor a colors tömb elemeit kibontjuk a tömbből és értékül adjuk a megadott változóknak.

  • first változó megkapja a colors[0] értékét.
  • second változó megkapja a colors[1] értékét.
  • third változó megkapja a colors[2] értékét.

Lehetőségünk van felbontani a tömböket úgy is, hogy egyes elemeket kihagyunk, vagy akár úgy is, hogy a számunkra fontos elemeket kiszedjük (ez az első valamennyi elem lehet), majd a maradékot egy "maradék tömbben" tároljuk, ehhez a rest operátort használhatjuk.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
let colors = ["red", "green", "blue", "yellow", "white", "black", "orange"];

// Skip elements
let [primary, , tertiary] = colors;
console.log(primary); // "red"
console.log(tertiary); // "blue"

// Rest operator
let [head, second, ...tail] = colors;
console.log(head);    // "red"
console.log(second);    // "green"
console.log("others", tail);    //  ['blue', 'yellow', 'white', 'black', 'orange']

Tömbök bejárása

Ha végig szeretnénk iterálni egy tömb elemein, akkor azt többféle módon tudjuk megtenni:

Hagyományos for ciklus

1
2
3
4
5
6
let cats = ["Garfield", "Nermal", "Grumpy Cat", "Tom"];

// traditional index-based iteration
for (let i = 0; i < cats.length; i++) {
    console.log(cats[i]);
}

Ennek előnye lehet, hogy tudjuk, hogy éppen hol járunk a tömbben, azonban a használata kényelmetlen lehet.

For-of ciklus (ajánlott)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
let cats = ["Garfield", "Nermal", "Grumpy Cat", "Tom"];

// list-like iteration - cat variable takes each array element value
for (let cat of cats) {
    console.log(cat);
}

// with index if needed
for (let [index, cat] of cats.entries()) {
    console.log(`${index}: ${cat}`);
}

forEach metódus

Funkcionális megközelítést is használhatunk, amikor is a tömbök létező forEach metódusát használjuk, egy callback függvénnyel, amelyet minden egyes elemre meg fog hívni.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
let cats = ["Garfield", "Nermal", "Grumpy Cat", "Tom"];

// functional approach
cats.forEach(function(cat, index) {
    console.log(`${index}: ${cat}`);
});

// with arrow function (modern)
cats.forEach((cat, index) => {
    console.log(`${index}: ${cat}`);
});

Itt természetesen használhatunk arrow függvényt is.

Alapvető tömbkezelő függvények

A JavaScript számos beépített függvényt biztosít tömbök kezelésére.

Elemek hozzáadása és eltávolítása

  • array.pop() törli (és visszaadja) az utolsó elemet
  • array.push(a, b, ...): beszúrja az elemeket a tömb végére
  • array.shift(): törli (és visszaadja) a legelső elemet
  • array.unshift(a, b, ...): beszúrja az elemeket a tömb elejére
1
2
3
4
5
6
7
8
let shoppingList = ["milk", "eggs", "cheese", "soda"];

shoppingList.pop();                        // remove from end
shoppingList.push("bread", "ham");         // add to end
shoppingList.shift();                      // remove from beginning
shoppingList.unshift("calculus textbook"); // add to beginning

console.log(shoppingList);

Kimenet

[ 'calculus textbook', 'eggs', 'cheese', 'bread', 'ham' ]

Keresés és rendezés

  • array.indexOf(element): visszaadja az elem legelső előfordulásának indexét (-1 ha nincs benne)
  • array.includes(element): igaz/hamis értéket ad vissza attól függően, hogy az elem szerepel-e a tömbben
  • array.sort(): rendezi a tömb elemeit (alapértelmezetten lexikografikus összehasonlítás szerint)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
let numbers = [3, 1, 4, 1, 5, 9];

console.log(numbers.indexOf(1));     // 1 (first occurrence)
console.log(numbers.includes(5));    // true
console.log(numbers.includes(7));    // false

numbers.sort();                      // sorts as strings by default!
console.log(numbers);                // [1, 1, 3, 4, 5, 9] - lucky this time

// Proper numeric sorting
numbers.sort((a, b) => a - b);       // ascending order
console.log(numbers);                // [1, 1, 3, 4, 5, 9]

numbers.sort((a, b) => b - a);       // descending order
console.log(numbers);                // [9, 5, 4, 3, 1, 1]

Darabolás és átalakítás

  • array.slice(startIndex, endIndex): visszaadja a tömb egy részét (új tömbben)
  • array.join(separator): egy stringgé egyesíti a tömböt
1
2
3
4
5
6
7
8
9
let shoppingList = ["calculus textbook", "eggs", "cheese", "bread", "ham"];

shoppingList.sort();                           // sort alphabetically
let asText = shoppingList.join("; ");          // join into text
console.log("We need to buy: " + asText);

let important = shoppingList.slice(1, 3);      // get "sub-array"
console.log("Buy these ASAP:");
console.log(important);

Kimenet

We need to buy: bread; calculus textbook; cheese; eggs; ham

Buy these ASAP:

[ 'calculus textbook', 'cheese' ]

Modern tömbkezelő metódusok (funkcionális)

Ezek a metódusok nem módosítják az eredeti tömböt, hanem új tömböt vagy értéket adnak vissza:

map() - Átalakítás

Minden elemre alkalmaz egy függvényt és új tömböt ad vissza:

1
2
3
4
5
6
7
8
9
let numbers = [1, 2, 3, 4, 5];

// Double each number
let doubled = numbers.map(x => x * 2);
console.log(doubled);                    // [2, 4, 6, 8, 10]

// Convert to strings
let strings = numbers.map(x => `Number: ${x}`);
console.log(strings);                    // ["Number: 1", "Number: 2", ...]

filter() - Szűrés

Csak azokat az elemeket tartja meg, amelyek megfelelnek egy feltételnek:

1
2
3
4
5
6
7
8
9
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

// Only even numbers
let evens = numbers.filter(x => x % 2 === 0);
console.log(evens);                      // [2, 4, 6, 8, 10]

// Only numbers greater than 5
let large = numbers.filter(x => x > 5);
console.log(large);                      // [6, 7, 8, 9, 10]

Spread operátor és Rest paraméterek

A tömböket "szétbonthatjuk" elemekre, ami néhol hasznos lehet, például, ha egy függvényt szeretnénk meghívni egy tömb elemeivel.

1
2
3
4
5
6
function printSecondParameter(a, b, c) {
    console.log(b);
}

let anArray = [2, 3, 4];
printSecondParameter(...anArray);

Vagy éppen, ha tömböket szeretnénk összeolvasztani.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
let numbers1 = [1, 2, 3];
let numbers2 = [4, 5, 6];

// Combine arrays
let combined = [...numbers1, ...numbers2];
console.log(combined);                   // [1, 2, 3, 4, 5, 6]

// Copy array (shallow copy)
let copy = [...numbers1];
console.log(copy);                       // [1, 2, 3]

// Add elements
let extended = [0, ...numbers1, 4];
console.log(extended);                   // [0, 1, 2, 3, 4]

// Find max/min
let max = Math.max(...numbers1);
console.log(max);                        // 3

// Convert string to array
let chars = [..."hello"];
console.log(chars);                      // ["h", "e", "l", "l", "o"]

Többdimenziós tömbök

JavaScriptben a többdimenziós tömbök valójában tömbök tömbje, ez hasonló a korábban tanultakhoz. Természetesen mindent ugyanúgy lehet csinálni, mint a hagyományos tömbökkel.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 2D array (matrix)
let matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
];

console.log(matrix[0][1]);               // 2 (first row, second column)
console.log(matrix[2][0]);               // 7 (third row, first column)

// Iterate through 2D array
for (let i = 0; i < matrix.length; i++) {
    for (let j = 0; j < matrix[i].length; j++) {
        console.log(`matrix[${i}][${j}] = ${matrix[i][j]}`);
    }
}

// Modern way with forEach
matrix.forEach((row, i) => {
    row.forEach((value, j) => {
        console.log(`matrix[${i}][${j}] = ${value}`);
    });
});

Metódusok összekombinálása (Method chaining)

A modern JavaScript egyik nagy erőssége, hogy a tömbmetódusokat láncolni tudjuk:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
// Example 1: Working with simple arrays of numbers
let grades = [85, 92, 78, 95, 88, 73, 91, 82];

// Find grades above 80, sort them in descending order
let highGrades = grades
    .filter(grade => grade > 80)        // grades above 80
    .sort((a, b) => b - a);             // sort descending
console.log(highGrades);                // [95, 92, 91, 88, 85, 82]


// Example 2: Working with arrays of strings
let fruits = ["apple", "banana", "cherry", "date", "elderberry", "fig"];

// Find fruits with more than 5 letters, convert to uppercase, sort alphabetically
let longFruits = fruits
    .filter(fruit => fruit.length > 5)   // more than 5 letters
    .map(fruit => fruit.toUpperCase())   // convert to uppercase
    .sort();                             // sort alphabetically
console.log(longFruits);                // ["BANANA", "CHERRY", "ELDERBERRY"]