8
votes

Compréhension de liste élégante Scala comme dans F #

Utiliser simplement l'interface JDBC de base pour lire certaines données à l'aide de SCALA. Dans F # (à l'aide de l'espace de noms System.Data.Sqlient), nous pourrions faire quelque chose comme ça pour renvoyer une liste immuable de la base de données. XXX PRE>

dans SCALA Cela s'avère plus difficile, autant que je sache là n'est pas «alors que la compréhension» comme F #. Effectivement, j'aimerais faire quelque chose près de F # dans Scala sans avoir à utiliser des vars mutables - si seulement parce qu'ils ont l'air moche et ajoute aux lignes de code. P>

Quelque chose comme ça semble être banal dans mon scala Code actuellement: P>

 var result = Seq.empty[Int]
 val rs = stmt.executeQuery()
 while (rs.next()) {
     result = result :+ rs.getInt(1) }


4 commentaires

En fait dans idiomatique scala, il ressemblerait à Val RS = stmt.executequerery (); Résultat Val = pour (R <- RS) Rendement R.Getint (1) (juste un pseudocode, si vous voulez)


Vous voudrez peut-être jeter un oeil à ce post: Stackoverflow.com/Questtions/2102662/...


Si vous recherchez des requêtes liées à Linq à Scala, jetez un coup d'œil à SLICK


OM-NOM-NOM: En fait, vous ne pouvez pas faire cela puisque RS est un jeu d'enregistrements et ne peut pas être itéré comme ça.


3 Réponses :


7
votes

Vous pouvez utiliser la même manière à Scala, mais je pense que c'est moche: xxx pre>

idiomatic scala way est de convertir votre lecteur code> à un itérateur : P>

import scala.collection.immutable.VectorBuilder
class FWhile(c: => Boolean){
  def apply[T](e: => T): Seq[T] = {
    val b = new VectorBuilder[T]
    while (c) b += e
    b.result
  }
}
object FWhile{
  def apply(c: => Boolean) = new FWhile(c)
}

scala> FWhile(r.read){r.getInt32}
res0: Seq[Int] = Vector(9, 8, 7, 6, 5, 4, 3, 2, 1)


1 commentaires

Très bonne réponse. Avoué toutes les autres réponses ici aussi qui sont excellentes.



9
votes

Je créerais une sous-classe personnalisée de itérateur code> qui enveloppe un résultat de la requête. C'est vraiment facile; Senia a montré comment.

Mais vous pouvez également P>

val rs = stmt.executeQuery
val it = Iterator.continually(if (rs.next()) Some(rs.getInt(1)) else None)
val result = it.takeWhile(_.isDefined).toList.flatten


0 commentaires

5
votes

Vous pouvez utiliser une classe implicite avec un CanbuildFrom code>. Cela utilise un constructeur mutable, mais pas au côté de l'appelant:

val keyNamesMap: Map[Int, String] = 
  rs.map(row => (row.getInt(2), row.getString(1)))


1 commentaires

@ OM-NOM-NOM mais cela détruirait la magie :-) J'ai ajouté une explication.