Utilizziamo i cookie per migliorare la tua esperienza sul sito
CodeWorlds

Tworzenie i manipulacja tablicami w JavaScript

Witaj ponownie w Parku Jurajskim! Dzisiaj będziemy zajmować się tablicami w JavaScript - strukturami danych, które są niezbędne do zarządzania kolekcjami obiektów, takich jak nasze gatunki dinozaurów, wyniki badań genetycznych czy dane z systemów monitorowania parku.

Czym są tablice?

Tablice to uporządkowane kolekcje elementów, które mogą przechowywać dane dowolnego typu. Można je porównać do szafek laboratoryjnych, gdzie każda szuflada (indeks tablicy) zawiera konkretną próbkę (element tablicy). Każdy element ma swój unikalny numer pozycji (indeks), który rozpoczyna się od 0.

Tworzenie tablic

W JavaScript istnieje kilka sposobów tworzenia tablic:

1. Literał tablicowy (najczęściej używany)

Najpopularniejszym sposobem jest użycie nawiasów kwadratowych

[]
:

1// Tablica gatunków dinozaurów w naszym parku
2const dinosaurs = ["Tyrannosaurus", "Velociraptor", "Triceratops", "Brachiosaurus"];
3
4// Tablica mieszanych typów danych (liczby, stringi, booleany)
5const dinoData = ["Blue", 5, true, 120.5];
6
7// Pusta tablica, do której będziemy dodawać elementy później
8const dinoEnclosures = [];

2. Konstruktor Array

Możemy również użyć konstruktora

Array()
:

1// Tablica utworzona za pomocą konstruktora
2const parkSectors = new Array("A", "B", "C", "D", "E");
3
4// Tablica z predefiniowaną długością, ale bez wartości
5const securityReadings = new Array(10); // Tworzy tablicę z 10 pustymi elementami
6
7// Uwaga: jeśli przekażemy tylko jedną liczbę, tworzy to tablicę o tej długości
8// Jeśli przekażemy wiele argumentów, tworzą one elementy tablicy
9const confusingArray = new Array(3); // Tablica o długości 3: [empty x 3]
10const normalArray = new Array(1, 2, 3); // Tablica z trzema elementami: [1, 2, 3]

3. Metoda Array.of() (ES6)

Aby uniknąć niejednoznaczności konstruktora Array(), można użyć Array.of():

1// Zawsze tworzy tablicę z przekazanymi elementami
2const weights = Array.of(5000); // [5000], a nie tablica długości 5000
3const measurements = Array.of(1, 2, 3, 4, 5); // [1, 2, 3, 4, 5]

4. Metoda Array.from() (ES6)

Ta metoda tworzy tablicę z obiektów podobnych do tablicy (np. kolekcji DOM) lub iterowalnych (np. stringów):

1// Tworzenie tablicy z iterowalnego obiektu (string)
2const dinoLetters = Array.from("TREX"); // ["T", "R", "E", "X"]
3
4// Tworzenie tablicy z mapowaniem
5const dinoAges = Array.from([5, 7, 3, 10], age => age * 2); // [10, 14, 6, 20]
6
7// Przykład z kolekcją DOM (w przeglądarce)
8// const dinoElements = Array.from(document.querySelectorAll('.dinosaur'));

Dostęp do elementów tablicy

Elementy tablicy są indeksowane od 0, co oznacza, że pierwszy element ma indeks 0, drugi 1, itd.

1const velociraptors = ["Blue", "Delta", "Echo", "Charlie"];
2
3// Dostęp do pojedynczych elementów
4console.log(velociraptors[0]); // "Blue"
5console.log(velociraptors[2]); // "Echo"
6
7// Modyfikacja elementu
8velociraptors[1] = "New Delta";
9console.log(velociraptors); // ["Blue", "New Delta", "Echo", "Charlie"]
10
11// Dostęp do nieistniejącego elementu zwraca undefined
12console.log(velociraptors[10]); // undefined

Długość tablicy

Właściwość

length
zwraca liczbę elementów w tablicy:

1const dinosaurs = ["T-Rex", "Velociraptor", "Triceratops"];
2console.log(dinosaurs.length); // 3
3
4// Możemy również modyfikować długość tablicy
5dinosaurs.length = 2;
6console.log(dinosaurs); // ["T-Rex", "Velociraptor"] - Triceratops został usunięty
7
8// Zwiększenie długości dodaje puste elementy
9dinosaurs.length = 5;
10console.log(dinosaurs); // ["T-Rex", "Velociraptor", empty x 3]

Podstawowe operacje na tablicach

Dodawanie elementów

Istnieje kilka sposobów dodawania elementów do tablicy:

1. Na końcu tablicy: push()

1const dinosaurs = ["T-Rex", "Velociraptor"];
2
3// Dodawanie na końcu
4dinosaurs.push("Triceratops");
5console.log(dinosaurs); // ["T-Rex", "Velociraptor", "Triceratops"]
6
7// push może dodać wiele elementów naraz
8dinosaurs.push("Brachiosaurus", "Stegosaurus");
9console.log(dinosaurs); // ["T-Rex", "Velociraptor", "Triceratops", "Brachiosaurus", "Stegosaurus"]
10
11// push zwraca nową długość tablicy
12const newLength = dinosaurs.push("Ankylosaurus");
13console.log(newLength); // 6

2. Na początku tablicy: unshift()

1const dinosaurs = ["Velociraptor", "Triceratops"];
2
3// Dodawanie na początku
4dinosaurs.unshift("T-Rex");
5console.log(dinosaurs); // ["T-Rex", "Velociraptor", "Triceratops"]
6
7// unshift również może dodać wiele elementów naraz
8dinosaurs.unshift("Spinosaurus", "Dilophosaurus");
9console.log(dinosaurs); // ["Spinosaurus", "Dilophosaurus", "T-Rex", "Velociraptor", "Triceratops"]
10
11// unshift także zwraca nową długość tablicy
12const newLength = dinosaurs.unshift("Compsognathus");
13console.log(newLength); // 6

3. Na konkretnej pozycji: splice()

1const dinosaurs = ["T-Rex", "Velociraptor", "Stegosaurus"];
2
3// Wstawianie elementu na pozycji 1 (jako drugi element)
4// splice(pozycja, ile_usunąć, elementy_do_dodania...)
5dinosaurs.splice(1, 0, "Triceratops");
6console.log(dinosaurs); // ["T-Rex", "Triceratops", "Velociraptor", "Stegosaurus"]
7
8// Zastępowanie elementu na pozycji 2
9dinosaurs.splice(2, 1, "Brachiosaurus");
10console.log(dinosaurs); // ["T-Rex", "Triceratops", "Brachiosaurus", "Stegosaurus"]
11
12// Możemy dodać wiele elementów naraz
13dinosaurs.splice(1, 0, "Ankylosaurus", "Dilophosaurus");
14console.log(dinosaurs); // ["T-Rex", "Ankylosaurus", "Dilophosaurus", "Triceratops", "Brachiosaurus", "Stegosaurus"]

Usuwanie elementów

Podobnie jak w przypadku dodawania, istnieje kilka metod usuwania elementów:

1. Z końca tablicy: pop()

1const dinosaurs = ["T-Rex", "Velociraptor", "Triceratops"];
2
3// Usuwanie ostatniego elementu
4const removedDino = dinosaurs.pop();
5console.log(removedDino); // "Triceratops"
6console.log(dinosaurs); // ["T-Rex", "Velociraptor"]

2. Z początku tablicy: shift()

1const dinosaurs = ["T-Rex", "Velociraptor", "Triceratops"];
2
3// Usuwanie pierwszego elementu
4const removedDino = dinosaurs.shift();
5console.log(removedDino); // "T-Rex"
6console.log(dinosaurs); // ["Velociraptor", "Triceratops"]

3. Z konkretnej pozycji: splice()

1const dinosaurs = ["T-Rex", "Velociraptor", "Triceratops", "Stegosaurus"];
2
3// Usuwanie jednego elementu na pozycji 1
4const removedDinos = dinosaurs.splice(1, 1);
5console.log(removedDinos); // ["Velociraptor"]
6console.log(dinosaurs); // ["T-Rex", "Triceratops", "Stegosaurus"]
7
8// Usuwanie wielu elementów zaczynając od pozycji 1
9const moreRemovedDinos = dinosaurs.splice(1, 2);
10console.log(moreRemovedDinos); // ["Triceratops", "Stegosaurus"]
11console.log(dinosaurs); // ["T-Rex"]

Znalezienie elementu w tablicy

1. indexOf() i lastIndexOf()

1const dinosaurs = ["T-Rex", "Velociraptor", "Triceratops", "Velociraptor"];
2
3// Znalezienie pierwszego wystąpienia
4const firstIndex = dinosaurs.indexOf("Velociraptor");
5console.log(firstIndex); // 1
6
7// Znalezienie ostatniego wystąpienia
8const lastIndex = dinosaurs.lastIndexOf("Velociraptor");
9console.log(lastIndex); // 3
10
11// Jeśli element nie istnieje, zwraca -1
12const notFoundIndex = dinosaurs.indexOf("Spinosaurus");
13console.log(notFoundIndex); // -1

2. includes() (ES6)

1const dinosaurs = ["T-Rex", "Velociraptor", "Triceratops"];
2
3// Sprawdzenie, czy element istnieje w tablicy
4const hasVelociraptor = dinosaurs.includes("Velociraptor");
5console.log(hasVelociraptor); // true
6
7const hasSpinosaurus = dinosaurs.includes("Spinosaurus");
8console.log(hasSpinosaurus); // false

3. find() i findIndex() (ES6)

Metody te są przydatne do wyszukiwania elementów złożonych (obiektów) na podstawie kryteriów:

1// Tablica obiektów dinozaurów
2const dinosaurData = [
3  { name: "Rex", species: "Tyrannosaurus", age: 16, dangerous: true },
4  { name: "Blue", species: "Velociraptor", age: 5, dangerous: true },
5  { name: "Spike", species: "Stegosaurus", age: 10, dangerous: false },
6  { name: "Trixie", species: "Triceratops", age: 18, dangerous: false }
7];
8
9// Znalezienie pierwszego dinozaura starszego niż 15 lat
10const oldDino = dinosaurData.find(dino => dino.age > 15);
11console.log(oldDino); // { name: "Rex", species: "Tyrannosaurus", age: 16, dangerous: true }
12
13// Znalezienie indeksu pierwszego bezpiecznego dinozaura
14const safeIndex = dinosaurData.findIndex(dino => !dino.dangerous);
15console.log(safeIndex); // 2 (Spike)

Kopiowanie i łączenie tablic

1. Kopiowanie tablicy za pomocą slice()

1const originalDinos = ["T-Rex", "Velociraptor", "Triceratops"];
2
3// Tworzenie kopii całej tablicy
4const dinosCopy = originalDinos.slice();
5console.log(dinosCopy); // ["T-Rex", "Velociraptor", "Triceratops"]
6
7// Kopiowanie części tablicy (od indeksu 1 do końca)
8const partialCopy = originalDinos.slice(1);
9console.log(partialCopy); // ["Velociraptor", "Triceratops"]
10
11// Kopiowanie zakresu (od indeksu 0 do 1, bez 2)
12const rangeCopy = originalDinos.slice(0, 2);
13console.log(rangeCopy); // ["T-Rex", "Velociraptor"]

2. Łączenie tablic za pomocą concat()

1const carnivores = ["T-Rex", "Velociraptor"];
2const herbivores = ["Triceratops", "Brachiosaurus", "Stegosaurus"];
3
4// Łączenie dwóch tablic
5const allDinos = carnivores.concat(herbivores);
6console.log(allDinos);
7// ["T-Rex", "Velociraptor", "Triceratops", "Brachiosaurus", "Stegosaurus"]
8
9// Można łączyć więcej tablic naraz
10const smallDinos = ["Compsognathus"];
11const allSpecies = carnivores.concat(herbivores, smallDinos);
12console.log(allSpecies);
13// ["T-Rex", "Velociraptor", "Triceratops", "Brachiosaurus", "Stegosaurus", "Compsognathus"]

3. Operator rozproszenia (spread) (ES6)

1const carnivores = ["T-Rex", "Velociraptor"];
2const herbivores = ["Triceratops", "Brachiosaurus"];
3
4// Łączenie tablic za pomocą spread
5const allDinos = [...carnivores, ...herbivores];
6console.log(allDinos); // ["T-Rex", "Velociraptor", "Triceratops", "Brachiosaurus"]
7
8// Można dodawać elementy w środku
9const mixedCollection = [...carnivores, "Dilophosaurus", ...herbivores];
10console.log(mixedCollection);
11// ["T-Rex", "Velociraptor", "Dilophosaurus", "Triceratops", "Brachiosaurus"]
12
13// Kopiowanie tablicy za pomocą spread
14const dinosCopy = [...carnivores];
15console.log(dinosCopy); // ["T-Rex", "Velociraptor"]

Przeszukiwanie i sortowanie tablic

1. Sortowanie tablicy: sort()

1const dinosaurs = ["Velociraptor", "Tyrannosaurus", "Brachiosaurus", "Ankylosaurus"];
2
3// Sortowanie alfabetyczne (domyślne)
4dinosaurs.sort();
5console.log(dinosaurs);
6// ["Ankylosaurus", "Brachiosaurus", "Tyrannosaurus", "Velociraptor"]
7
8// Sortowanie liczb (wymaga funkcji porównującej)
9const dinoWeights = [5000, 500, 15000, 7000];
10
11// Bez funkcji porównującej - nieprawidłowo sortuje liczby jako stringi
12dinoWeights.sort();
13console.log(dinoWeights); // [15000, 500, 5000, 7000] (niepoprawnie!)
14
15// Z funkcją porównującą - poprawne sortowanie rosnąco
16dinoWeights.sort((a, b) => a - b);
17console.log(dinoWeights); // [500, 5000, 7000, 15000]
18
19// Sortowanie malejąco
20dinoWeights.sort((a, b) => b - a);
21console.log(dinoWeights); // [15000, 7000, 5000, 500]

2. Sortowanie obiektów

1const dinosaurData = [
2  { name: "Rex", species: "Tyrannosaurus", age: 16 },
3  { name: "Blue", species: "Velociraptor", age: 5 },
4  { name: "Spike", species: "Stegosaurus", age: 10 },
5  { name: "Trixie", species: "Triceratops", age: 18 }
6];
7
8// Sortowanie po wieku (rosnąco)
9dinosaurData.sort((a, b) => a.age - b.age);
10console.log(dinosaurData.map(dino => `${dino.name} (${dino.age})`));
11// ["Blue (5)", "Spike (10)", "Rex (16)", "Trixie (18)"]
12
13// Sortowanie po nazwie (alfabetycznie)
14dinosaurData.sort((a, b) => a.name.localeCompare(b.name));
15console.log(dinosaurData.map(dino => dino.name));
16// ["Blue", "Rex", "Spike", "Trixie"]

3. Odwracanie kolejności: reverse()

1const dinosaurs = ["T-Rex", "Velociraptor", "Triceratops", "Brachiosaurus"];
2
3// Odwrócenie kolejności elementów
4dinosaurs.reverse();
5console.log(dinosaurs); // ["Brachiosaurus", "Triceratops", "Velociraptor", "T-Rex"]

Przekształcanie tablic

1. Konwersja na string: join()

1const dinosaurs = ["T-Rex", "Velociraptor", "Triceratops"];
2
3// Łączenie wszystkich elementów w string z domyślnym separatorem (przecinek)
4const dinoString = dinosaurs.join();
5console.log(dinoString); // "T-Rex,Velociraptor,Triceratops"
6
7// Z niestandardowym separatorem
8const dinoList = dinosaurs.join(" | ");
9console.log(dinoList); // "T-Rex | Velociraptor | Triceratops"
10
11// Bez separatora
12const dinoNoSeparator = dinosaurs.join("");
13console.log(dinoNoSeparator); // "T-RexVelociraptorTriceratops"

2. Konwersja string na tablicę: split()

1const dinoString = "T-Rex,Velociraptor,Triceratops";
2
3// Rozdzielenie stringa na tablicę
4const dinosaurs = dinoString.split(",");
5console.log(dinosaurs); // ["T-Rex", "Velociraptor", "Triceratops"]
6
7// Rozdzielenie po każdym znaku
8const letters = "TREX".split("");
9console.log(letters); // ["T", "R", "E", "X"]

Praktyczne przykłady pracy z tablicami

Przykład 1: System inwentaryzacji dinozaurów

1// System inwentaryzacji dinozaurów w Parku Jurajskim
2const dinosaurInventory = {
3  species: [],
4
5  // Dodawanie nowego gatunku do inwentarza
6  addSpecies: function(name, count, carnivore) {
7    // Sprawdzenie czy gatunek już istnieje
8    const existingIndex = this.species.findIndex(s => s.name === name);
9
10    if (existingIndex >= 0) {
11      // Aktualizacja istniejącego gatunku
12      this.species[existingIndex].count += count;
13      console.log(`Zaktualizowano populację ${name}: ${this.species[existingIndex].count}`);
14    } else {
15      // Dodanie nowego gatunku
16      this.species.push({
17        name,
18        count,
19        carnivore,
20        addDate: new Date().toISOString().split('T')[0]
21      });
22      console.log(`Dodano nowy gatunek: ${name} (liczba osobników: ${count})`);
23    }
24
25    return this;
26  },
27
28  // Usuwanie dinozaurów (np. w wyniku śmierci lub transferu)
29  removeSpecimens: function(name, count, reason) {
30    const index = this.species.findIndex(s => s.name === name);
31
32    if (index === -1) {
33      console.log(`Gatunek ${name} nie istnieje w inwentarzu.`);
34      return false;
35    }
36
37    if (this.species[index].count < count) {
38      console.log(`Błąd: Próbujesz usunąć więcej osobników (${count}) niż istnieje (${this.species[index].count}).`);
39      return false;
40    }
41
42    this.species[index].count -= count;
43    console.log(`Usunięto ${count} osobników gatunku ${name}. Powód: ${reason}.`);
44    console.log(`Pozostało: ${this.species[index].count} osobników.`);
45
46    // Jeśli nie ma już żadnych osobników, usuń gatunek z inwentarza
47    if (this.species[index].count === 0) {
48      const removed = this.species.splice(index, 1)[0];
49      console.log(`Gatunek ${removed.name} został całkowicie usunięty z inwentarza.`);
50    }
51
52    return true;
53  },
54
55  // Generowanie podsumowania inwentarza
56  generateSummary: function() {
57    console.log("=== PODSUMOWANIE INWENTARZA DINOSAURÓW ===");
58
59    if (this.species.length === 0) {
60      console.log("Brak dinozaurów w inwentarzu.");
61      return;
62    }
63
64    // Sortowanie gatunków według liczebności (malejąco)
65    const sortedSpecies = [...this.species].sort((a, b) => b.count - a.count);
66
67    // Liczba gatunków i osobników
68    const totalSpecies = sortedSpecies.length;
69    const totalSpecimens = sortedSpecies.reduce((sum, species) => sum + species.count, 0);
70    console.log(`Liczba gatunków: ${totalSpecies}`);
71    console.log(`Łączna liczba osobników: ${totalSpecimens}`);
72
73    // Podział na mięsożerne i roślinożerne
74    const carnivores = sortedSpecies.filter(s => s.carnivore);
75    const herbivores = sortedSpecies.filter(s => !s.carnivore);
76
77    console.log(`Gatunki mięsożerne: ${carnivores.length}`);
78    console.log(`Gatunki roślinożerne: ${herbivores.length}`);
79
80    // Najbardziej liczne gatunki
81    if (sortedSpecies.length > 0) {
82      console.log("
83Największa populacja:");
84      sortedSpecies.slice(0, 3).forEach((species, i) => {
85        console.log(`${i+1}. ${species.name}: ${species.count} osobników`);
86      });
87    }
88
89    // Tabela wszystkich gatunków
90    console.log("
91Szczegółowy wykaz gatunków:");
92    console.log("Nazwa | Liczebność | Typ | Data dodania");
93    console.log("------|------------|-----|-------------");
94    sortedSpecies.forEach(species => {
95      const type = species.carnivore ? "Mięsożerny" : "Roślinożerny";
96      console.log(`${species.name.padEnd(6)} | ${String(species.count).padEnd(10)} | ${type.padEnd(4)} | ${species.addDate}`);
97    });
98  }
99};
100
101// Testowanie systemu inwentaryzacji
102dinosaurInventory.addSpecies("T-Rex", 3, true);
103dinosaurInventory.addSpecies("Velociraptor", 12, true);
104dinosaurInventory.addSpecies("Triceratops", 8, false);
105dinosaurInventory.addSpecies("Brachiosaurus", 5, false);
106dinosaurInventory.addSpecies("Gallimimus", 20, false);
107
108// Aktualizacja istniejących gatunków
109dinosaurInventory.addSpecies("Velociraptor", 4, true); // Dodanie 4 nowych Velociraptorów
110
111// Usuwanie osobników
112dinosaurInventory.removeSpecimens("T-Rex", 1, "Śmierć ze starości");
113dinosaurInventory.removeSpecimens("Gallimimus", 5, "Transfer do innego parku");
114
115// Generowanie podsumowania
116dinosaurInventory.generateSummary();

Przykład 2: Analiza danych genetycznych

1// Przykładowe dane genetyczne (uproszczone) jako tablica
2const geneticData = [
3  { id: "TRX01", species: "Tyrannosaurus", sequenceMatch: 0.85, viability: "High", complete: true },
4  { id: "VLR02", species: "Velociraptor", sequenceMatch: 0.93, viability: "Medium", complete: true },
5  { id: "TRC04", species: "Triceratops", sequenceMatch: 0.79, viability: "Low", complete: false },
6  { id: "BRCH1", species: "Brachiosaurus", sequenceMatch: 0.81, viability: "Medium", complete: true },
7  { id: "STEG7", species: "Stegosaurus", sequenceMatch: 0.76, viability: "Low", complete: false },
8  { id: "ANKL5", species: "Ankylosaurus", sequenceMatch: 0.88, viability: "High", complete: true },
9  { id: "DILO3", species: "Dilophosaurus", sequenceMatch: 0.91, viability: "Medium", complete: false },
10  { id: "PTRD9", species: "Pteranodon", sequenceMatch: 0.72, viability: "Low", complete: false }
11];
12
13// Funkcje analizy danych
14function analyzeGeneticData(data) {
15  console.log("=== ANALIZA DANYCH GENETYCZNYCH ===");
16
17  // 1. Ile sekwencji jest kompletnych?
18  const completeSequences = data.filter(seq => seq.complete);
19  console.log(`Kompletne sekwencje: ${completeSequences.length} z ${data.length} (${((completeSequences.length / data.length) * 100).toFixed(1)}%)`);
20
21  // 2. Średni współczynnik dopasowania sekwencji
22  const averageMatch = data.reduce((sum, seq) => sum + seq.sequenceMatch, 0) / data.length;
23  console.log(`Średnie dopasowanie sekwencji: ${(averageMatch * 100).toFixed(1)}%`);
24
25  // 3. Wyodrębnij najlepsze i najgorsze dopasowania
26  const sortedByMatch = [...data].sort((a, b) => b.sequenceMatch - a.sequenceMatch);
27
28  console.log("
29Najlepsze dopasowania sekwencji:");
30  sortedByMatch.slice(0, 3).forEach((seq, i) => {
31    console.log(`${i+1}. ${seq.species} (ID: ${seq.id}): ${(seq.sequenceMatch * 100).toFixed(1)}%`);
32  });
33
34  console.log("
35Najgorsze dopasowania sekwencji:");
36  sortedByMatch.slice(-3).reverse().forEach((seq, i) => {
37    console.log(`${i+1}. ${seq.species} (ID: ${seq.id}): ${(seq.sequenceMatch * 100).toFixed(1)}%`);
38  });
39
40  // 4. Grupowanie według zdolności do życia (viability)
41  const viabilityGroups = data.reduce((groups, seq) => {
42    if (!groups[seq.viability]) {
43      groups[seq.viability] = [];
44    }
45    groups[seq.viability].push(seq);
46    return groups;
47  }, {});
48
49  console.log("
50Grupowanie według zdolności do życia:");
51  Object.entries(viabilityGroups).forEach(([viability, sequences]) => {
52    console.log(`${viability}: ${sequences.length} sekwencji`);
53    sequences.forEach(seq => {
54      console.log(`  - ${seq.species} (ID: ${seq.id})`);
55    });
56  });
57
58  // 5. Filtry sekwencji priorytetowych do dalszych badań
59  const highPrioritySequences = data.filter(seq =>
60    seq.sequenceMatch > 0.85 && !seq.complete
61  );
62
63  console.log("
64Sekwencje priorytetowe do dokończenia:");
65  if (highPrioritySequences.length > 0) {
66    highPrioritySequences.forEach(seq => {
67      console.log(`- ${seq.species} (ID: ${seq.id}): dopasowanie ${(seq.sequenceMatch * 100).toFixed(1)}%, zdolność do życia: ${seq.viability}`);
68    });
69  } else {
70    console.log("Brak sekwencji priorytetowych.");
71  }
72
73  return {
74    totalSequences: data.length,
75    completeSequences: completeSequences.length,
76    averageMatch,
77    bestMatch: sortedByMatch[0],
78    worstMatch: sortedByMatch[sortedByMatch.length - 1],
79    viabilityDistribution: Object.fromEntries(
80      Object.entries(viabilityGroups).map(([key, val]) => [key, val.length])
81    ),
82    highPrioritySequences
83  };
84}
85
86// Wykonanie analizy
87const analysisResults = analyzeGeneticData(geneticData);
88console.log("
89Wynik analizy jako obiekt:", analysisResults);
90
91// Filtrowanie i manipulacja danych
92console.log("
93=== MANIPULACJA DANYMI ===");
94
95// 1. Stworzenie nowej tablicy tylko z wybranymi polami
96const simplifiedData = geneticData.map(seq => ({
97  id: seq.id,
98  species: seq.species,
99  match: seq.sequenceMatch
100}));
101console.log("Uproszczone dane:", simplifiedData);
102
103// 2. Filtrowanie do pokazania tylko kompletnych sekwencji z wysokim dopasowaniem
104const highQualitySequences = geneticData.filter(seq =>
105  seq.complete && seq.sequenceMatch > 0.8
106);
107console.log("Sekwencje wysokiej jakości:", highQualitySequences);
108
109// 3. Sortowanie według gatunku alfabetycznie
110const sortedBySpecies = [...geneticData].sort((a, b) =>
111  a.species.localeCompare(b.species)
112);
113console.log("Sortowanie alfabetycznie według gatunku:",
114  sortedBySpecies.map(seq => seq.species)
115);
116
117// 4. Łączenie z inną tablicą (nowe dane)
118const newGeneticData = [
119  { id: "PCHY1", species: "Pachycephalosaurus", sequenceMatch: 0.83, viability: "Medium", complete: true },
120  { id: "SPNO5", species: "Spinosaurus", sequenceMatch: 0.89, viability: "High", complete: false }
121];
122
123const combinedData = [...geneticData, ...newGeneticData];
124console.log(`Połączone dane: ${combinedData.length} sekwencji`);
125
126// 5. Łączenie w string do raportu CSV
127const csvHeader = "ID,Gatunek,Dopasowanie,Żywotność,Kompletne";
128const csvRows = combinedData.map(seq =>
129  `${seq.id},${seq.species},${seq.sequenceMatch},${seq.viability},${seq.complete}`
130);
131const csvReport = [csvHeader, ...csvRows].join('\n');
132console.log("Raport CSV:");
133console.log(csvReport);

Zaawansowane metody tablicowe (ES6+)

Nowoczesny JavaScript dostarcza wielu potężnych metod do pracy z tablicami, które znacznie upraszczają przetwarzanie danych.

1. map() - transformacja elementów

Metoda

map()
tworzy nową tablicę przez transformację każdego elementu oryginalnej tablicy:

1const dinosaurs = [
2  { name: "Rex", species: "Tyrannosaurus" },
3  { name: "Blue", species: "Velociraptor" },
4  { name: "Spike", species: "Stegosaurus" }
5];
6
7// Pobranie tylko imion
8const names = dinosaurs.map(dino => dino.name);
9console.log(names); // ["Rex", "Blue", "Spike"]
10
11// Tworzenie nowych obiektów
12const dinoLabels = dinosaurs.map(dino => ({
13  label: `${dino.name} (${dino.species})`,
14  id: dino.name.toLowerCase()
15}));
16console.log(dinoLabels);
17// [
18//   { label: "Rex (Tyrannosaurus)", id: "rex" },
19//   { label: "Blue (Velociraptor)", id: "blue" },
20//   { label: "Spike (Stegosaurus)", id: "spike" }
21// ]

2. filter() - filtrowanie elementów

Metoda

filter()
tworzy nową tablicę zawierającą tylko elementy, które spełniają określone kryterium:

1const dinosaurs = [
2  { name: "Rex", species: "Tyrannosaurus", carnivore: true, weight: 7000 },
3  { name: "Blue", species: "Velociraptor", carnivore: true, weight: 100 },
4  { name: "Spike", species: "Stegosaurus", carnivore: false, weight: 5000 },
5  { name: "Trixie", species: "Triceratops", carnivore: false, weight: 8000 }
6];
7
8// Filtrowanie tylko drapieżników
9const carnivores = dinosaurs.filter(dino => dino.carnivore);
10console.log(carnivores.map(dino => dino.name)); // ["Rex", "Blue"]
11
12// Filtrowanie ciężkich dinozaurów
13const heavyDinos = dinosaurs.filter(dino => dino.weight > 1000);
14console.log(heavyDinos.map(dino => dino.name)); // ["Rex", "Spike", "Trixie"]
15
16// Łączenie warunków
17const heavyCarnivores = dinosaurs.filter(dino => dino.carnivore && dino.weight > 1000);
18console.log(heavyCarnivores.map(dino => dino.name)); // ["Rex"]

3. reduce() - agregacja elementów

Metoda

reduce()
redukuje tablicę do pojedynczej wartości, przechodząc przez wszystkie elementy:

1const dinosaurs = [
2  { name: "Rex", species: "Tyrannosaurus", weight: 7000 },
3  { name: "Blue", species: "Velociraptor", weight: 100 },
4  { name: "Spike", species: "Stegosaurus", weight: 5000 },
5  { name: "Trixie", species: "Triceratops", weight: 8000 }
6];
7
8// Obliczanie łącznej wagi
9const totalWeight = dinosaurs.reduce((sum, dino) => sum + dino.weight, 0);
10console.log(`Łączna waga dinozaurów: ${totalWeight} kg`); // 20100 kg
11
12// Znajdowanie najcięższego dinozaura
13const heaviestDino = dinosaurs.reduce(
14  (heaviest, dino) => dino.weight > heaviest.weight ? dino : heaviest,
15  dinosaurs[0]
16);
17console.log(`Najcięższy dinozaur: ${heaviestDino.name} (${heaviestDino.weight} kg)`);
18// Najcięższy dinozaur: Trixie (8000 kg)
19
20// Tworzenie obiektu mapującego gatunki na dinozaury
21const dinosBySpecies = dinosaurs.reduce((acc, dino) => {
22  acc[dino.species] = dino;
23  return acc;
24}, {});
25
26console.log(dinosBySpecies.Velociraptor.name); // "Blue"

4. some() i every() - testowanie elementów

Metody te sprawdzają, czy niektóre/wszystkie elementy spełniają określone kryterium:

1const dinosaurs = [
2  { name: "Rex", species: "Tyrannosaurus", dangerous: true, contained: true },
3  { name: "Blue", species: "Velociraptor", dangerous: true, contained: false },
4  { name: "Spike", species: "Stegosaurus", dangerous: false, contained: true }
5];
6
7// Sprawdzenie, czy jakikolwiek dinozaur jest niebezpieczny
8const anyDangerous = dinosaurs.some(dino => dino.dangerous);
9console.log("Czy jakiś dinozaur jest niebezpieczny?", anyDangerous); // true
10
11// Sprawdzenie, czy wszystkie dinozaury są bezpiecznie zamknięte
12const allContained = dinosaurs.every(dino => dino.contained);
13console.log("Czy wszystkie dinozaury są bezpiecznie zamknięte?", allContained); // false
14
15// Sprawdzenie, czy wszystkie niebezpieczne dinozaury są zamknięte
16const allDangerousContained = dinosaurs
17  .filter(dino => dino.dangerous)
18  .every(dino => dino.contained);
19console.log("Czy wszystkie niebezpieczne dinozaury są zamknięte?", allDangerousContained); // false

5. flat() i flatMap() (ES2019)

Metody te spłaszczają zagnieżdżone tablice:

1// Zagnieżdżona tablica dinozaurów według zagród
2const enclosures = [
3  ["Rex", "Rexy"], // Zagroda T-Rexów
4  ["Blue", "Delta", "Echo"], // Zagroda Velociraptorów
5  ["Spike", "Spikey"], // Zagroda Stegozaurów
6  [] // Pusta zagroda
7];
8
9// Spłaszczanie do pojedynczej tablicy
10const allDinos = enclosures.flat();
11console.log(allDinos); // ["Rex", "Rexy", "Blue", "Delta", "Echo", "Spike", "Spikey"]
12
13// Bardziej złożony przykład z flatMap
14const enclosureData = [
15  { type: "T-Rex", dinosaurs: ["Rex", "Rexy"] },
16  { type: "Velociraptor", dinosaurs: ["Blue", "Delta", "Echo"] },
17  { type: "Stegosaurus", dinosaurs: ["Spike", "Spikey"] }
18];
19
20// Mapowanie i spłaszczanie w jednym kroku
21const dinosaursWithTypes = enclosureData.flatMap(enclosure =>
22  enclosure.dinosaurs.map(dino => `${dino} (${enclosure.type})`)
23);
24
25console.log(dinosaursWithTypes);
26// [
27//   "Rex (T-Rex)",
28//   "Rexy (T-Rex)",
29//   "Blue (Velociraptor)",
30//   "Delta (Velociraptor)",
31//   "Echo (Velociraptor)",
32//   "Spike (Stegosaurus)",
33//   "Spikey (Stegosaurus)"
34// ]

Podsumowanie

Tablice są jedną z najpotężniejszych struktur danych w JavaScript, pozwalając na przechowywanie, organizowanie i manipulowanie kolekcjami elementów. W tym module poznaliśmy:

  1. Różne sposoby tworzenia tablic: literały tablicowe, konstruktor Array(), metody Array.of() i Array.from()
  2. Podstawowe operacje na tablicach: dodawanie elementów (push, unshift, splice), usuwanie elementów (pop, shift, splice), dostęp do elementów
  3. Metody wyszukiwania: indexOf, includes, find, findIndex
  4. Metody kopiowania i łączenia: slice, concat, operator spread (...)
  5. Metody sortowania i porównywania: sort, reverse
  6. Metody przekształcania: join (na string), split (ze stringa)
  7. Zaawansowane metody przetwarzania: map, filter, reduce, some, every, flat, flatMap

Umiejętność efektywnego wykorzystania tablic jest niezbędna w codziennej pracy z JavaScript, szczególnie gdy zarządzamy dużymi zbiorami danych, takimi jak nasz wirtualny inwentarz dinozaurów.

W następnym module zajmiemy się metodami tablic, które pozwalają na iterowanie po ich elementach i wykonywanie operacji dla każdego z nich.

Vai a CodeWorlds