nav_dugme codeBlog codeBlog
  • početna Početna stranica
  • Sačuvani članci Sačuvani članci
  • Učionica
  • Saveti
  • Zanimljivosti
  • Kontakt

Operacije sa nizovima u programskom jeziku JavaScript

Viber
zoom_plus zoom_minus bookmark

Uvod

Nizovi u Javascript-u deklarišu se i inicijalizuju na vrlo komotan način, ne podležu tipizaciji (niz može sadržati elemente različitog tipa), interna implementacija nizova je prilično kompleksna, a - ako bismo baš hteli - našli bismo bar još koju zamerku.

Međutim, mora se priznati da u radu sa nizovima u JS-u ima šarma i lepote (ima i svega navedenog iz prethodne rečenice; nismo zaboravili) i mora se priznati da u praksi - naravno, sve pod uslovom da "pazimo šta radimo" - stvari funkcionišu prilično glatko.

Pristup koji predlažemo čitaocima (i koji primenjujemo u praksi), podrazumeva da - kada već programski jezik dozvoljava "sve i svašta" - vođenje računa o bitnim stvarima preuzmemo na sebe, i sa nizovima postupamo onako kako bismo postupali da koristimo jezik sa strogom tipizacijom.

U takvim okolnostima, Javascript nam neće priređivati neprijatna iznenađenja.

Nizovi u Javascript-u uopšteno

Za početak, valja razmotriti šta se (uopšte) u Javascript-u podrazumeva pod pojmom "niz", jer krajnji rezultat zavisi od endžina koji se koristi, * pa ne možemo biti sigurni šta se dešava "ispod haube" (gde "niz" može biti zapisan: bilo kao statički niz, bilo kao hash-mapa, sve u zavisnosti od okolnosti).

* Javascript endžin je program koji se koristi za interpretaciju JS koda unutar drugog programa, tipično, unutar browsera (najpoznatiji JS endžini su V8, koji koriste Google Chrome i Node JS, i Sea Monkey, koji koristi Mozilla Firefox).

Ovoga puta, bićemo praktični i nećemo ulaziti u detaljnu diskusiju o implementaciji nizova (ovom tematikom ćemo se svakako pozabaviti u doglednoj budućnosti), ali ćemo za sada definisati nizove u Javascript-u kao posebne promenljive koje omogućavaju smeštanje više podataka preko jednog identifikatora (naziva promenljive), pri čemu dati podaci ne moraju biti istog tipa, a moguće je i proizvoljno dodavanje i uklanjanje elemenata.

Deklaracija

Osnovni vid deklaracije niza u JS-u (praktično) podrazumeva i inicijalizaciju praznog niza u istoj liniji koda (jer, ukoliko izostavimo inicijalizaciju, promenljiva neće biti referenca na niz, već objekat sa sistemskom vrednošću null):

		
let niz = [];
		
	
Slika 1. - Deklaracija niza u Javascript-u.

Niz je prazan, ali svakako mu se u daljem radu mogu dodavati elementi.

Inicijalizacija

Pored inicijalizacije praznog niza (kakvu smo već videli), često se javlja i inicijalizacija/deklaracija koja podrazumeva zadavanje (nekoliko) elemenata:

		
let niz   = [ 1, 2, 2, 3, 4, 5, 5 ];
let imena = [ "Milan", "Petar", "Jovan" ];
		
	
Slika 2. - Inicijalizacija niza u Javascript-u.

Takođe, niz može biti inicijalizovan i preko funkcija koje vraćaju nizove.

		
let niz = funkcijaKojaVracaNiz(ulaz);

// Primer:

let s     = "papir;kamen;makaze";
let lista = s.split(";"); // [ "papir" , "kamen" , "makaze" ]
		
	
Slika 3. - Inicijalizacija niza u Javascript-u - preko funkcije koja vraća niz.

Što se tiče inicijalizacija koje smo videli na slici #3, na scenu stupa "preuzimanje odgovornosti" sa naše strane.

Ako za inicijalizaciju koristimo funkciju koju smo sami definisali, postaraćemo se da funkcija: ili uredno inicijalizuje niz, ili da vrati izlaznu vrednost po kojoj ćemo prepoznati da je došlo do greške (ne moramo obavezno koristiti izuzetke i try-catch blok, ali svakako nećemo prihvatati "zdravo za gotovo" da je niz uredno inicijalizovan).

Ukoliko koristimo gotova rešenja, konsultovaćemo dokumentaciju i ponovo biti pažljivi.

.... a sa funkcijom split ćemo se detaljnije upoznati u nastavku.

Pristup elementima

Pristup elementima niza obavlja se na uobičajen način, navođenjem indeksa u velikoj zagradi.

		
let imeOsobe = imena[2]; // "Jovan"
		
	
Slika 4. - Pristup elementu niza u Javascript-u.

Kao i u C-u, indeksiranje počinje nulom (pa je u nizu od 5 elemenata, poslednji indeks koji možemo koristiti 4).

Očitavanje dužine niza - length

Dužinu niza (broj elemenata), možemo odrediti navođenjem sledećeg koda (preko svojstva length):

		
let d = niz.length;
		
	
Slika 5. - Određivanje dužine niza u Javascript-u.

Sada možemo (recimo) napraviti i for petlju koja će pristupiti svim elementima:

		
for (let i = 0; i < d; ++i) {
	niz[i] = niz[i] + 1;
}
		
	
Slika 6. - For petlja u kojoj se koristi prethodno ustanovljena dužina niza.

Kao i mnogi drugi jezici, Javascript takođe raspolaže i "specijalizovanom for petljom" forEach - koja je specifično namenjena prolasku kroz ceo niz (čemu ćemo više pažnje posvetiti pred kraj).

Dodavanje elementa na kraj niza

Za dodavanje elementa na kraj niza, koristi se komanda push:

		
// [ 1, 2, 2, 3, 4, 5, 5 ]
niz.push(10); // [ 1, 2, 2, 3, 4, 5, 5, 10 ]
		
	
Slika 7. - Funkcija push - dodavanje elementa na kraj niza.

Za dodavanje elementa (ili elemenata) na proizvoljnu poziciju, koristi se komanda splice (više o tome u nastavku).

Uklanjanje elemenata

Kada je u pitanju uklanjanje elemenata, razlikujemo tri slučaja:

  • uklanjanje elementa sa kraja niza
  • uklanjanje elementa sa početka niza
  • uklanjanje elementa sa proizvoljne pozicije

Element sa kraja niza uklanja se preko komande pop:

		
// niz: [ 1, 2, 2, 3, 4, 5, 5, 10 ]
let p = niz.pop();

// p:   10
// niz: [ 1, 2, 2, 3, 4, 5, 5 ]
		
	
Slika 8. - Funkcija pop - Uklanjanje elementa sa kraja niza.

Element sa početka niza uklanja se preko komande shift:

		
// niz: [ 1, 2, 2, 3, 4, 5, 5 ]
let p = niz.shift();

// p:   1
// niz: [ 2, 2, 3, 4, 5, 5 ]
		
	
Slika 9. - Funkcija shift - Uklanjanje elementa sa početka niza.

Kada je u pitanju uklanjanje elementa sa proizvoljne pozicije, koristi se (već pomenuta) funkcija splice, s tim da je u pitanju univerzalna komanda preko koje je moguće obaviti: i dodavanje, i uklanjanje.

Funkcija splice - dodavanje i/ili uklanjanje elemenata na proizvoljnoj poziciji

Poslednje što smo naveli može delovati pomalo čudno, ali, komanda splice je veoma univerzalna i može se koristiti za obe operacije:

		
niz.splice(indeks, n_brisanje, elementi_za_dodavanje ....);

// indeks     - indeks na kome se obavlja dodavanje, ili
//              od koga počinje uklanjanje
// n_brisanje - broj elemenata koje treba ukloniti
// elementi   - lista elemenata koji će biti dodati
		
	
Slika 10. - Funkcija splice - Univerzalna funkcija za uklanjanje i dodavanje elemenata.

Reč u nazivu funkcije - "splice" (koja je takođe pomalo čudna), u prevodi označava "uplitanje", a u praksi takvo uplitanje podrazumeva i presecanje na određenom mestu (zarad dodavanja novog elementa, ili zarad uklanjanja postojećih elemenata).

Kao što vidimo, zaista veoma univerzalno, ali - kako to (sve) funkcioniše u praksi?!

Dodavanje elemenata

Za dodavanje elemenata, postavićemo indeks na poziciju koja odgovara mestu na kome želimo da se pojavi prvi element iz liste novih elemenata i naglasiti da se nijedan element ne uklanja (drugi argument je 0). Od trećeg argumenta počinje lista elemenata koji se umeću.

Ako je i indeks za umetanje, a n broj elemenata za umetanje, cela operacija podrazumeva umetanje liste od n elemenata između pozicija i i i + 1.

		
let niz = [ 1 , 2 , 3 , 4 , 5 ]

niz.splice(2, 0, 1001, 1002)
// [ 1 , 2 , 1001 , 1002 , 3 , 4 , 5 ] 
		
	
Slika 11. - Primer dodavanja elemenata preko funkcije splice.

U konkretnom primeru, između druge i treće pozicije, umeću se dva nova elementa (1001, 1002).

Uklanjanje elemenata

Za uklanjanje elemenata, navodimo dva parametra: indeks prvog elementa koji je potrebno ukloniti i ukupan broj elemenata koje je potrebno ukloniti.

		
let niz = [ 1 , 2 , 3 , 4 , 5 ]

niz.splice(2, 1)
// [ 1 , 2 , 4 , 5 ] 
		
	
Slika 12. - Primer uklanjanja elemenata preko funkcije splice.

U konkretnom primeru, na 3. poziciji (indeks 2) uklonili smo jedan element.

Ako funkciji predamo (samo) dva argumenta, jasno je da nema dodavanja.

Kombinovani pristup

Po potrebi, prethodna dva pristupa je moguće kombinovati.

Prvo se uklanja određen broj elemenata (onoliko koliko je navedeno preko drugog argumenta) - počevši od indeksa koji je naveden kao prvi argument, pa se zatim umeću novi elementi, na mesto koje (praktično) odgovara poziciji na kojoj je došlo do uklanjanja.

		
let niz = [ 1 , 2 , 3 , 4 , 5 ]

niz.splice(2, 2, 2001, 2002)
// [ 1 , 2 , 2001, 2002, 5 ] 
		
	
Slika 13. - Primer kombinovanog uklanjanja i dodavanja preko funkcije splice.

U konkretnom primeru, prvo se uklanjaju elementi sa indeksima 2 i 3 (dva elementa, počevši od indeksa 2), a zatim se između novih indeksa 1 i 2 (ili, uslovno rečeno, između prvobitnih indeksa 1 i 4) umeću novi elementi (2001 i 2002).

Spajanje nizova

U Javascript-u, dva niza možemo spojiti na sledeći način:

		
let a = [ 1, 2, 3 ];
let b = [ 4, 5, 6 ];
let c = a.concat(b); // [ 1, 2, 3, 4, 5, 6 ]
		
	
Slika 14. - Funkcija concat - Spajanje nizova.

"Concat" je skraćenica od "concatenate" (ili "concatenation"). Konkatenacija je (u praksi malo previše "zvaničan") termin koji označava spajanje nizova znakova (ali se u većem broju programskih jezika, kao što vidimo, koristi i za operaciju spajanja nizova opšteg tipa).

Sortiranje nizova

Možemo naravno implementirati i sopstvene funkcije za sortiranje nizova, ali, možemo umesto toga jednostavno pozvati sledeći kod.

		
let a = [ 2, 1, 3, 5, 4 ];
a.sort(); // [ 1, 2, 3, 4, 5 ]
		
	
Slika 15. - Funkcija sort - Uređivanje niza u neopadajući poredak.

U praksi (pogotovo za jednostavne primere), više nego prihvatljivo (složenost je O(nlogn)).

Spajanje niza u nisku znakova

Ukoliko želimo da niz elemenata spojimo u nisku, možemo koristiti komandu join:

		
let a  = [ "N", "i", "z", "o", "v", "i" ];
let s1 = a.join();    // "Nizovi"
let s2 = a.join("*"); // "N*i*z*o*v*i"
		
	
Slika 16. - Funkcija join - Spajanje elemenata niza u nisku znakova.

U obradi tekstualnih datoteka, komanda join (baš kao i komanda split, koju ćemo prikazati u narednom odeljku), koristi se često.

Pretvaranje niske znakova u niz

Deljenje niske, obavlja se preko funkcije split, a kao kriterijum za podelu može se koristiti određena niska ili regularni izraz:

		
let s = "Pariz-London-Lisabon";
let a = s.split("-"); // [ "Pariz", "London", "Lisabon" ]
		
	
Slika 17. - Funkcija split - Kreiranje niza podelom niske znakova.

Kao što je pomenuto, funkcije join i split jako dobro dođu u obradi teksta, pa tako, na primer, možemo pravilno formatirati listu imena u kojoj se separatori (znakovi za razdvajanje), ne koriste na dosledan način:

		
// Dobre informacije, ali, nedosledna
// upotreba znakova za razdvajanje:
let s = "Milan Ivan, Jovan # Dejan";

// Regex je praktično kolekcija svih "razdvajača":
let regex = /([ ,#])/

let lista = s.split(regex); // [ "Milan", " " , "Ivan", ",",
                            //   " ", "Jovan", " ", "#",
                            //   " " , "Dejan" ]

// Napomena: u praksi, lista bi sadržala i nekoliko
// praznih stringova ("")

let nova_lista = [];

for (let i = 0; i < lista.length; ++i) {
	// Ako je element liste prazna niska ili neki
	// od separatora, nećemo takav element ubacivati
	// u novu listu:
	if (lista[i] == "" || lista[i].match(regex)) {
		continue;
	}
	
	// Sve ostale elemente (praktično - samo imena),
	// ubacićemo u novu listu:
	nova_lista.push(lista[i]);
}

// Na kraju, spojićemo listu u ("običnu") nisku,
// u kojoj će svako ime biti zapisano u novom redu

let s2 = nova_lista.join("\n");
		
	
Slika 18. - Praktičan primer korišćenja funkcija split i join.

Nisku smo rastavili preko funkcije split, prošli smo kroz sve elemente liste (koja je nastala rastavljanjem niske), izdvojili smo imena i na kraju smo od liste formirali ("običnu") nisku, preko funkcije join.

Funkcije višeg reda za rad sa nizovima

Funkcije koje smo nabrojali u ovom članku nisu naravno (ni iz daleka) sve funkcije koje se u JS-u koriste za rad sa nizovima, već samo one koje smatramo najkorisnijim za sam početak.

Iako smo članak namenili korisnicima sa ne-baš-mnogo iskustva, osvrnućemo se i na nekoliko (ponešto) naprednijih funkcija za rad sa nizovima koje se obično koriste u sprezi sa tzv. "lambda" notacijom.

Ne dajte da vas navedeni termini zaplaše, jer, u pitanju je prilično jednostavan način zapisa koji većina programera (čak i mlađih i/ili neiskusnijih) može lako prihvatiti intuitivno, a, kada bude došlo vreme, možete se detaljno upoznati sa sintaksom funkcija povratnih poziva i lambda izraza (ostavićemo pred kraj link prema članku koji smo posvetili navedenim temama).

every

Sledeći kod ....

		
a.every(x => x > 1);
		
	
Slika 19. - Funkcija every, koja proverava da li svaki element niza zadovoljava određeni kriterijum.

.... vratiće true pod uslovom da su svi elementi niza veći od 1 (u suprotnom, vratiće false).

some

Sledeći kod ....

		
a.some(x => x > 10);
		
	
Slika 20. - Funkcija some, koja proverava da li bar jedan element niza zadovoljava određeni kriterijum.

.... vratiće true pod uslovom da je bar jedan element niza veći od 10 (u suprotnom, vratiće false).

map

Ukoliko želimo da kopiramo niz i pri tom novim elementima dodelimo određene vrednosti preko funkcije, možemo koristiti sledeću sintaksu:

		
let a = [ 1, 2, 3, 4, 5 ];
let b = a.map(x => x * x);
		
	
Slika 21. - Funkcija map, koja kreira kopiju niza prema pravilu koje je određeno unutrašnjom funkcijom.

Pokretanjem poslednje skripte, nastaće novi niz sa vrednostima 1, 4, 9, 16 i 25 (koje predstavljaju kvadrate vrednosti iz ulaznog niza).

filter

Ukoliko je potrebno da, pri kopiranju niza, uklonimo određene vrednosti, možemo koristiti komandu filter.

Cela operacije podrazumeva kreiranje novog niza, u koji će biti kopirane samo vrednosti koje zadovoljavaju uslov:

		
let a = [ 1, 2, 3, 4, 5 ];
let b = a.filter(x => x > 3);
		
	
Slika 22. - Funkcija filter, koja u novi niz kopira samo određene elemente, shodno uslovu.

U primeru sa gornje slike, novi niz sadržaće samo elemente 4 i 5.

forEach

Za pojednostavljeni zapis petlje koja prolazi kroz ceo niz (kao što smo već nagovestili), možemo koristiti sledeću sintaksu:

		
let a = [ 1, 2, 3, 4, 5 ];

a.forEach(element => {
	console.log(element);
});
		
	
Slika 23. - Funkcija forEach, koja obilazi sve elemente niza.

Primećujemo da kod u slučaju funkcije forEach elementima ne pristupamo preko indeksa, već preko reference element.

Sintaksa deluje intuitivno, međutim, forEach nije petlja, nego (lambda) funkcija, pa tako (na primer) za prekid ciklusa nećemo koristiti rezervisanu reč break, već return.

Kao što rekosmo, intuitivno jeste, ali, da biste za prave razumeli ono što smo naveli, biće neophodno da se (što pre, tim bolje) upoznate sa funkcijama povratnog poziva i lambda izrazima, za šta možete iskoristiti članak koji smo posvetili navedenim temama.

Za kraj ....

Kao što smo videli, rad sa nizovima u JS-u nije nikakav "bauk" (naravno, uz opasku da svakako moramo voditi više računa nego u strogo tipiziranim jezicima, gde ipak postoje određeni mehanizmi koji će nas sprečiti da u niz celobrojnih vrednosti dodajemo niske i slično).

Sledeći članak o JS-u posvetićemo implementaciji čvorova i struktura podataka u ovom programskom jeziku ....

Autor članka Nikola Vukićević Za web portal www.codeblog.rs
Napomena: Tekstovi, slike, web aplikacije i svi ostali sadržaji na sajtu www.codeblog.rs (osim u slučajevima gde je drugačije navedeno) predstavljaju intelektualnu svojinu autora sajta www.codeblog.rs i zabranjeno je njihovo korišćenje na drugim sajtovima i štampanim medijima, kao i bilo kakvo drugo korišćenje u komercijalne svrhe, bez eksplicitnog pismenog odobrenja autora.
© 2020-2023. Sva prava zadržana.
Viber
početna Početna > Članci > Operacije sa nizovima u programskom jeziku JavaScript

Info & povezani članci Info o članku - dugme

Info

trejler_sat Datum objave: 25.12.2020.

trejler_sat Poslednja izmena: ----

trejler_dokument Jezici: Javascript

trejler_teg_narandzasti Težina: 6/10

Povezani članci

Uvod u Javascript i DOM Strukture podataka Tutorijal: Implementacija binarnog stabla pretrage u programskom jeziku JavaScript Regularni izrazi - napredna pretraga teksta Tutorijal - Regex - Kako pronaći unutrašnji sadržaj HTML elemenata Tutorijal - Regex i JavaScript - Korišćenje regularnih izraza u programskim jezicima JSON - tekstualni format za predstavljanje objekata Uvod u web dizajn - 1. deo - Početni koraci Napredna Google pretraga Ostali članci
Perl – The only language that looks the same before and after RSA encryption.
Keith Bostic
codeBlog codeBlog
Projekat posvećen popularizaciji kulture i veštine programiranja.
Napomena: Tekstovi i slike na sajtu www.codeblog.rs (osim u slučajevima, gde je drugačije navedeno) predstavljaju intelektualnu svojinu autora sajta www.codeblog.rs i zabranjeno je njihovo korišćenje na drugim sajtovima i štampanim medijima, kao i bilo kakvo drugo korišćenje u komercijalne svrhe, bez eksplicitnog odobrenja autora.
© 2020-2023. Sva prava zadržana.
Facebook - logo
Instagram - logo
LinkedIn - logo
Twitter - logo
E-mail
Naslovna
   •
Uslovi korišćenja
   •
Obaveštenja
   •
FAQ
   •
Kontakt