2. Sisällysluettelo
6A. LISTA
1. Lista: list, cons, first, rest, append, length, empty?
2. Lista: member?, remove, remove-all, list-ref
3. range
6B. LISTA JA REKURSIO
4. Listan ”syöminen” rekursiivisesti
5. Listan luominen rekursiivisesti
6C. LISTA JA HIGHER ORDER FUNKTIONS
6. map, foldl, foldr
2
3. Lista
list, cons, first, rest
Lista on tietorakenne, johon voi tallentaa mitä tahansa tietoa. Tyhjään listaan
viitataan Racket-kielessä sanalla empty tai symbolilla ’().
Listan luominen:
(list 1 2 3 4 5 6)
Uuden alkion lisääminen valmiiseen listaan (lisätään aina alkuun):
(cons 7 (list 1 2 3 4 5 6)) -> (list 7 1 2 3 4 5 6)
Listan ensimmäisen alkion palauttaminen (myös second, third):
(first (list 7 1 2 3 4 5 6)) -> 7
Listan loppuosan palauttaminen (esimmäinen alkio poistetaan).
(rest (list 7 1 2 3 4 5 6)) -> (list 1 2 3 4 5 6)
3
4. Lista
append, length, empty?
Listojen yhdistäminen
(append (list 1 2 3)(list 4 5 6))-> (list 1 2 3 4 5 6)
Listan pituuden kysyminen
(length (list 1 2 3 4)) -> 4
Tyhjän listan tunnistaminen
(empty? ’()) -> #true
(empty? (list 1 2)) -> #false
Listassa voi olla mitä tahansa (merkkijonoja, kuvia, listoja, totuusarvoja...):
(list 3 ”Tiina” (list 1 2 3) #t)
4
5. Lista
member?, remove, remove-all, list-ref
Voit tutkia onko alkio listan jäsen
(member? 3 (list 4 5 6))-> #false
Voit poistaa alkion listasta
(remove 4 (list 1 2 3 4)) -> (list 1 2 3)
Voit poistaa kaikki tietyt alkiot
(remove-all 2 (list 1 2 3 2 4) -> (list 1 3 4)
Ottaa listasta tietyssä kohtaa sijaitsevan alkion (ensimmäinen alkio 0)
(list-ref (list 10 20 30) 1) -> 20
5
6. range
Range – funktio palauttaa aritmeettisen lukujonon listan muodossa. Sille
annetaan argumentiksi luku josta lähdetään, luku johon lopetataan sekä
askel
(range 0 10 1) -> (list 0 1 2 3 4 5 6 7 8 9)
(range 5 30 5) -> (list 5 10 15 20 25)
Askel voi olla myös negatiivinen
(range 30 5 -5) -> (list 25 20 15 10 5)
Käytämme tätä apuna Higher Order – funktioiden kanssa
6
7. Listan ”syöminen” rekursiivisesti
Silmukkarakennetta voidaan käyttään esim. lista- tai puutyyppisen tietorakenteen
läpi käymiseen. Silloin ei tarvita laskuria, koska silmukan toiminta voidaan lopettaa
kun tietorakenne on käyty loppuu (esim. saavutettu listan pää).
Esim. Luetellaan ruokalista
(require teachpacks/display-read)
(define (syö-listaa lista)
(if (empty? lista)
(display-info-timer "Lista loppui” 50)
(begin (display-info-timer (first lista) 50)
(syö-listaa (rest lista)))))
(syö-listaa (list "cokis" "ranskalaiset" "jäätelö"))
7
8. Listan luominen rekursiivisesti
(listaan kerätään kuvia)
Lista voi olla myös akkumulaattorin paikalla, eli voit kerätä tuloksia listaan.
(require 2htdp/image)
(define (tähtiä i lista)
(if (<= i 0)
lista
(tähtiä (sub1 i)(cons (star (* i 10) "solid" "aqua") lista))))
(tähtiä 8 empty)
8
uusi tähti
lisää uuden alkion listaan
10. Higher Order Funktiot
Jos tehtävänä on tehdä ennalta tiedetty määrä toistoja, voidaan käyttää
Higher Order – funktioita toiston toteuttamiseen.
Higher Order – funktiot ovat funktioita, jotka voivat ottaa toisen
funktion argumenttina (tavalliset funktiot ovat First Order – funktioita).
Racket:in Higer Order – funktiot käsittelevät tietota listojen muodossa.
Higher Order – funktioita ovat mm. map, apply, filter, foldl, foldr ja
quicksort
10
11. map
map on Higher Order – funktio, joka ottaa argumenttina funktion sekä
listan ja syöttää listan alkiot yksi kerrallaan funktiolle. map palauttaa
saadut paluuarvot listan muodossa. Esim. neliö-funktio (sqr)
(map sqr (list 1 2 3 4 5)) -> (list 1 4 9 16 25)
map:ille on aivan sama mitä funktio tekee ja mitä listassa on. Voimme esim.
tehdä listan tähtikuvia. Teemme ensin apufunktion tähti, jolla on yksi parametri
(koko):
(define (tähti koko)
(star koko ”solid” ”red”))
(map tähti (list 5 10 15 20 25 30))
->
11
Listassa tähtien koot
12. apply
apply ottaa argumenttina funktion sekä listan arvoja, jotka syötetään ko.
funktiolle argumenteiksi. Esim. Voisimme laskea yhteen listan alkiot:
(apply + (list 1 2 3 4 5 6 7)) -> 28
Myös tämä funktio voi käsitellä mitä tahansa arvoja esim. kuvia. Voimme
esim. tehdä sisäkkäisiä ympyröitä. Teemme ensin apufunktio ”ympyrä”:n
avulla listan eri kokoisia ympyröitä ja sitten laitamme ne päällekkäin
käyttämällä apply:ä ja overlay:tä:
(define (ympyrä koko)
(circle koko ”outline” ”black”))
(map ympyrä (list 5 10 15 20 25 30)) ->
(apply overlay
(map ympyrä (list 5 10 15 20 25 30))) ->
12
13. foldl, foldr
foldl ja foldr toimivat myös funktioille, joilla on rajattu määrä argumentteja (vrt. + ja overlay
ottavat sisäänsä niin monta argumenttia kuin halutaan antaa). Tässä esimerkki, jossa place-image
sijoittaa kuvan annettuun koordinaattipisteeseen (x, y) annetun kuvan päälle. Tässä x ja y koordinaatit
sekä sijoitettavat kuvat voidaan antaa listoina ja taustakuva toimii ns. pohja-arvona (vrt.
akkumulaattori). Nämä funktiot palauttavat yhden arvon (ei listaa). Liitä-kuva toimii apufunktiona
(hoitaa yhden kuvan).
(define SIJAINTI-X (list 122 48 20 15 104 112 99 100 148))
(define SIJAINTI-Y (list 132 17 20 53 82 51 132 31 101))
(define TÄHDET )
(define (liitä-kuva kuva x y pohja)
(place-image kuva x y pohja))
(foldl liitä-kuva (empty-scene 150 150 "black")
TÄHDET
SIJAINTI-X
SIJAINTI-Y)
13
”pohja-arvo”