k47.cz    — každý den dokud se vám to nezačne líbit
foto Praha výběr povídky kultura | twitter FB


Scala - konverze TupleN na case class

23. 3. 2012 — k47

V projektu chanminer používám pro dotazování relační databáze ScalaQuery, která vrací instance TupleN neboli uspořádané n-tice (a tak je to správně). Někdy je potřeba převést tuto n-tici na objekt určité třídy, která má všechny potřebné metody a popisná jména členských proměnných.


Představte si, že mám třídu Post:

case class Post(
  uid: Int, board: String, threadId: Int, id: Int,
  postername: String, tripcode: String, text: String)

Databázový dotaz mi vrátí Tuple7[Int, String, Int, Int, String, String, String] jako například:

val t = (9, "b", 323822047, 323856408, "Anonymous", "", "reported")

Převedení n-tice na instanci třídy není nijak zvlášť zapeklité:

def makePost(t: (Int, String, Int, Int, String, String, String)) =
  Post(t._1, t._2, t._3, t._4, t._5, t._6, t._7)

Nebo s pomocí zázraků pattern matchingu:

def makePost2(t: (Int, String, Int, Int, String, String, String)) = {
  val (uid, board, threadId, id, postername, tripcode, text) = t
  Post(uid, board, threadId, id, postername, tripcode, text)
}

Tohle řešení funguje, ale je zdlouhavé a s každým dalším prvkem v n-tici/třídě přibude dalších pár znaků.

Naštěstí máme při ruce zázrak konverze metody na funkční objekt a jeho metodu tupled + fakt, že každá case class má svůj companion objekt s metodou apply, která slouží jako zkrácený kontruktor (však víte: Post(...) se expanduje na Post.apply(...) a apply volá new Post(...)).

Takže když tohle všechno víme, můžeme konverzi provést mnohem stručněji:

val makePostApply = (Post.apply _).tupled
val post: Post = makePostApply(t)

Pro obyčejné třídy musíme napsat o několik podtržítek více:

val makePostNew = (new Post(_, _, _, _, _, _, _)).tupled
val post: Post = makePostNew(t)

Případně si tuto metodu definovat přímo na companion objektu:

object Post { val fromTuple = (Post.apply _).tupled }

vstoupit do diskuze    sdílet na facebooku, twitteru, google+
publikováno 23. 3. 2012

příbuzné články:
Scala - Booleovská kompozice funkcí 📷
Scala - String interpolation 📷
Conway's game of life
Scala - líné parametry, líné závislosti a líné proxy 📷
Sleeping patterns
Scala - trait Dynamic 📷

sem odkazují:
Prog smetí

píše k47 & hosté, ascii@k47.cz