7. Nizovi i upravljači

Hajde da napišemo program koji traži od nas da upišemo onoliko riječi koliko želimo (jednu riječ po liniji, sve dok ne pritisnemo Enter u praznoj liniji), a nakon toga ponavlja te riječi po abecednom redu. OK?

Pa...prvo ćemo,...hm...ovaj... moglo bi se...mmm...

Znate šta, mislim da to ne možemo napraviti. Treba nam nešto što će pohraniti nepoznat broj riječi i držati ih sve na broju, da se ne bi pomiješale sa drugim varijablama/promjenjivim. Trebaće nam dakle nizovi.

Najjednostavnije rečeno, nizovi predstavljaju liste na vašem računaru. Svako mjesto u nizu ponaša se kao varijabla: možete vidjeti na kojem mjestu se nalazi određeni objekat i možete takođe ukazati i na neki drugi objekat unutar tog niza. Da pogledamo kako izgledaju neki nizovi:

[]

[5]

['Hello', 'Goodbye']

flavor = 'vanilla' # Ovo, naravno, nije niz…

[89.9, flavor, [true, false]] # ...ali ovo jeste.

Dakle, prvo imamo prazan niz, onda niz koji sadrži samo jedan broj, nakon toga niz koji sadrži dvije riječi (string). Poslije toga dolazi jednostavno dodijeljivanje varijable; onda niz koji sadrži tri objekta, od kojih je poslijednji i sam niz [true, false]. Upamtite, varijable nisu objekti, tako da naš poslijednji niz sadrži slijedeće objekte: float, string i niz [array]. Čak i ako bismo podesili 'flavour' da ukazuje na nešto drugo, to ne bi promijenilo niz.

Da bismo mogli naći određeni objekt u nizu, sva popunjena mjesta u niz su brojčano indeksirana. Programeri (kao i većina matematičara) počinju brojati od nule, tako da prvo mjesto (slot) u kome je smješten neki objekat ima 0 u indeksu. Evo kako bismo uspostavili vezu brojčanog indeksa i objekata u nizu:

names = ['Ada', 'Belle', 'Chris']

puts names

puts names[0]

puts names[1]

puts names[2]

puts names[3] # Ovaj indeks je nepostojeći.

Ispis:

Ada

Belle

Chris

Ada

Belle

Chris

nil

Dakle, možemo vidjeti da –puts names- ispisuje svako od imena u nizu names. Nakon toga koristimo –puts names[0]- da bismo dobili ispis objekta koji je na prvom mjestu u nizu, -puts names[1]- za ispis slijedećeg,... Siguran sam da bi s početka moglo zvučati zbunjujuće, ali navikne se čovjek, brzo. Jednostavno se morate prilagoditi mišljenju da brojanje počinje od nule, a prestati misliti da riječ prvi odgovara tom broju. Na ruci postoji pet prstiju, a njihovi su brojevi 0,1,2,3 i 4. Na kraju, shvatit ćete kako su indeksirani objekti u nizu kad počnete za redati objekt od „nultog“. Da , nulti je prava riječ; postoji; pitajte bilo kojeg programera ili matematičara.

Konačno, pokušali smo ispisati –puts names[3]-, samo da bi vidjeli šta se desi. Očekivali ste grješku? Ponekad, kad postavite neko pitanje, a ono nema smisla (bar ne za računar) onda u ispisu dobijete grješku. S druge strane, ponekad možete postaviti pitanje a da njegov odgovor bude „ništa“ [nil]. Šta je na mjestu koje nosi indeks [3]? Ništa. „Nil“ je način na koji nam Ruby poručuje da se na indeksu [3] našeg niza ne nalazi ništa,...a „nil“ se tretira kao objekat koji znači nepostojanje bilo kakvog objekta.

Ako vas plaši svo ovo nabrajanje, koje mjesto koji objekat zauzima u nizovima, ne bojte se! Često ih možemo izbjeći koristeći neke od metoda karakteristične za nizove, kao naprimjer:

Metoda „each“

-each- nam dozvoljava da učinimo nešto (bilo šta da želimo) sa svakim pojedinim bojektom sadržanom u nekom nizu. Tako dakle, ako želimo reći nešto lijepo o svakom od jezika u nizu, onda ćemo napisati slijedeći kod:

languages = ['English', 'German', 'Ruby']

languages.each do |lang|

puts 'I love ' + lang + '!'

puts 'Don\'t you?'

end

puts 'And let\'s hear it for C++!'

puts '...'

Ispis:

I love English!

Don't you?

I love German!

Don't you?

I love Ruby!

Don't you?

And let's hear it for C++!

...

Šta se upravo desilo? Uspjeli smo proći kroz sve objekte u nizu, a nismo morali da nabrajamo svaki pojedinačno, koristeći indeksirane brojeve za poziciju u nizu. Prevedeno na jezik početnika, pređašnji program razumijeva to kao naredbu: „za svaki objekat u nizu languages napravi varijablu lang koja će ukazati na objekat unutar niza i onda učini sve što ti kažem dok ne dođeš do kraja niza, odnosno kraja metode“. (Jedna mala opaska: među brojnim programskim jezicima, postoji i jedan zvani C++, kojega je daleko teže naučiti od Ruby; obično C++ program ima mnogo više linija nego bi imao neki program sa istom svrhom napisan u Ruby.)

Možda se zapitate, „Ova metoda je slična kružnoj petlji [loop], koji smo naučili u poglavlju prije ovoga.“ Da, slična jeste. Međutim, jedna vrlo važna razlika je da je –each- samo to: metoda; dok while i end nisu metode (kao što to nisu do, if, else). Ove rezervisane riječi su dijelovi Ruby kao programskog jezika, baš kao što su to znakovi =, ili zagrade; ne neki način kao znakovi interpunkcije u jeziku.

Ali ne i –each-; -each- je metoda namijenjena nizovima. Metode koje služe kao kruženje (kružne petlje), kao što je –each-, često se nazivaju upravljači ili ITERATORI.

Jedna fina stvar kod ITERATORA je da su uvijek praćeni riječima do . . . end. Druge, poput while i if, nikad nisu trebale do u svojoj bilizini; koristimo ih samo kod ITERATORA.

Slijedi još jedan mali primjer ITERATORA, ali ne kao metode namijenjene nizu nego kao ...integer metode!

3.times do

puts 'Hip-Hip-Hooray!'

end

Ispis:

Hip-Hip-Hooray!

Hip-Hip-Hooray!

Hip-Hip-Hooray!

Još nekoliko metoda namijenjenih nizovima

Dakle, naučili smo metodu –each-, međutim, ima još dosta njih koje su namijenjene nizovima, gotovo jednak broj koliko ih postoji i za string objekte! Ustvari, neke od njih (kao što su –length-, -reverse-, -+- i -*-) rade isto onako kako bi radile i sa stringovima, osim što rade na pozicijama objekata u stringu, a ne na znakovima koje sadrži string. Druge metode, kao što su –last- i –join- specifične su samo za nizove. Ima i onih kao što su –push- i -pop-, koje zapravo mogu izmijeniti niz. Ono što sam ranije rekao za pamćenje metoda za stringove, važi i za metode koje su posvećene nizovima; ne morate ih pamtiti sve dok vam je poznato gdje ćete ih pronaći (ovdje).

Prvo ćemo pogledati -.to_s- i –join- metode. –join- metoda radi slično metodi -.to_s- , a razlika je što dodaje string između dva objekta u nizu. Da pogledamo:

foods = ['artichoke', 'brioche', 'caramel']

puts foods

puts

puts foods.to_s

puts

puts foods.join(', ')

puts

puts foods.join(' :) ') + ' 8)'

200.times do

puts []

end

Ispis:

artichoke

brioche

caramel

artichokebriochecaramel

artichoke, brioche, caramel

artichoke :) brioche :) caramel 8)

Kao što možete vidjeti, -puts- tretira nizove različito od ostalih objekata: jednostavno poziva put string za svaki od objekata u nizu. Iz tog razlova „putsovanje“ praznog niza 200 puta neće dati nikakav rezultat; niz ne ukazuje na bilo kakve objekte, pa tako ni za metodu –puts- nema ničega što bi ispisala. (Uraditi ništa 200 puta jednačko je ničemu.) Pokušajte „putsovati“ neki niz koji sadrži nizove kao objekte; da li je rezultat ono što ste očekivali?

Takođe, da li ste primjetili da sam ispred –puts- stavio prazan string svaki put kad bih htio dobiti novi prazan red u ispisu?

Da sada pređemo na metode –push-, -pop- i –last-. Metode –push- i –pop- su opozitne, slično opoziciji koju predstavljaju i +. Metoda –push- dodaje objekat na kraj niza, a metoda –pop- uklanja objekat sa poslijednjeg mjesta u nizu (usput govoreći koji je to objekat). Metoda –last- slična je metodi –pop- utoliko što govori koji se objekat nalazi na poslijednjem mjestu u nizu, ali ne vrši nad njim nikakvu operaciju. Što je važno, metode –push- i -pop- ustvari vrše izmjene na nizu:

favorites = []

favorites.push 'raindrops on roses'

favorites.push 'whiskey on kittens'

puts favorites[0]

puts favorites.last

puts favorites.length

puts favorites.pop

puts favorites

puts favorites.length

Ispis:

raindrops on roses

whiskey on kittens

2

whiskey on kittens

raindrops on roses

1

Par stvarčica za oprobati

    • Napišite program o kome smo pričali na početku. (Caka: postoji jedna divna metoda za sortiranje objekata u nizu: -sort- Iskoristite ga!)
    • Pokušajte isti program napisati bez korištenja metode –sort-. Dobar dio programiranja je ustvari riješavanje problema, dajte se onda u vježbu!
    • Napišite ponovo program „SADRŽAJ“ (iz poglavlja o metodama). Počnite program s nizom koji će sadržavati sve naslove koje sadržaj treba da ima (ime poglavlja, broj strane,...). Onda ispišite informacije iz niza u divno formatiran „SADRŽAJ“.

Mnogo je metoda koje smo do sada naučili. Sad je vrijeme da naučimo i sami praviti metode. Naše vlastite.

------------------------------------------------

© 2003-2009 Chris Pine

http://pine.fm/LearnToProgram/