Tuesday, February 25, 2020

14 - az immutable generic List osztály

Természetesen a lista mint adatszerkezet annyira alap komponense a funkcionális programozás eszköztárának, hogy van belőle built-in, nem kell újra írnunk mindig egyet. Nagyon sokrétű, a funkcionalitásai egy részével össze fogunk ismerkedni a félév során, mindenesetre:
  • A típus neve List (teljes neve scala.collection.immutable.List, de a Scala Predef objektumában szerepel mint type alias, ezért látszik a rövid neve is.
  • Generic típus, a lista elemeinek típusát kapja paraméterként. Pl. az eddigi (1,4,2,8,5,7) példánk List[Int] típusúnak felel meg.
  • Az eddigi Ures objektumunknak (amit genericként egyelőre csak mint case classt tudtunk összehozni) megfelelő üres lista a Nil nevű objektum. Igen, objektum, és mindenféle típusú generic listának megfelel, ezt később jobban meg fogjuk érteni.
  • Az eddigi Nemures lista objektumunknak megfelelő osztály neve ::. Két kettőspont. Tehát akár így is létrehozhatunk egy (1,4,2) értéket a mostani tudásunk alapján:
    
    val list: List[Int] = ::(1,::(4,::(2,Nil)))
    
  • A :: osztály nevét a fenti prefix (avagy lengyel) jelölés helyett infix is használhatjuk konstruáláskor, így szokás (és figyeljük meg, hogy ennek is ki tudja következtetni a type inference, hogy List[Int] lesz:
    
    val list = 1 :: 4 :: 2 :: Nil
    
  • A companion object apply metódusának köszönhetően így is létrehozhatjuk ugyanezt:
    
    val list = List(1,4,2,8,5,7)
    
  • A List[T]-ben egyebek mellett szerepelnek a filter(p:TBoolean):List[T] és a map[U](f:TU):List[U] függvények, pontosan ugyanazzal a viselkedéssel, mint amit az előző posztokban láttunk.
  • A toString metódusa visszaadja a List szót, majd zárójelek közé zárva vesszővel elválasztva a lista elemeit.
  • Lehet rá mintailleszteni, az elv ugyanúgy megy, mint a saját korábbi implementációnkban: a nemüres listának van egy feje és egy farka, head::tail-ként is illeszthető rá a minta, így szoktuk kiírni, de persze fordul a ::(head,tail) minta is.
  • Egy hasznos metódusa a zip, ami egy másik listával "pároztatja össze" úgy, hogy egy List[T] zipje egy List[U] zipjével egy (T,U) párokat tartalmazó lista, vagyis egy List[(T,U)] lesz: az első elemek párja fogja alkotni a zipelt lista első elemét, a másodikoké a másodikat, stb, azaz pl. List(1,2,3).zip List("dinnye","szilva","narancs") értéke List((1,"dinnye"),(2,"szilva"),(3,"narancs")). Az ilyen pároknak, melyekből az eredménylista áll, egyébként az első mezőjét a _1, a második mezőjét a _2 adattagjukkal érjük el. Ha a zipelt listák hossza nem azonos, akkor a rövidebb lista hossza lesz az eredmény hossza, a hosszabb lista "leeső" farka nem számít az eredménybe.
  • Amiért a zip pl. hasznos tud lenni: ha egy list nemüres listát zipelünk a farkával: list.zip(list.tail), az, ha belegondolunk, a szomszédos elemeket teszi egy cellába, pl. List(1,4,2,8).zip(List(4,2,8))=List((1,4),(4,2),(2,8)). Ez hasznos lehet akkor, ha ez alapján akarunk mapni vagy filterezni.

No comments:

Post a Comment