J'ai des problèmes avec la plupart des opérations de base de Scala et cela me rend fou.
val a = Array(1,2,3)
println(a) and result is [I@1e76345
println(a.toString()) and result is [I@1e76345
println(a.toString) and result is [I@1e76345
Quelqu'un peut-il me dire comment imprimer un tableau sans écrire ma propre fonction pour le faire parce que c'est bête. Merci!
mkString
convertira les collections (y compris Array
) élément par élément en représentations sous forme de chaîne.
println(a.mkString(" "))
est probablement ce que vous voulez.
Vous pouvez faire la chose normale (voir la réponse de Rex ou de Jiri), ou vous pouvez:
scala> Array("bob","sue")
res0: Array[String] = Array(bob, sue)
Hé, pas juste! Le REPL l'a imprimé en vrai Nice.
scala> res0.toString
res1: String = [Ljava.lang.String;@63c58252
Pas de joie jusqu'à:
scala> runtime.ScalaRunTime.stringOf(res0)
res2: String = Array(bob, sue)
scala> runtime.ScalaRunTime.replStringOf(res0, res0.length)
res3: String =
"Array(bob, sue)
"
scala> runtime.ScalaRunTime.replStringOf(res0, 1)
res4: String =
"Array(bob)
"
Je me demande s'il y a un paramètre de largeur dans le REPL. Mise à jour: il n'y en a pas. Il est fixé à
val maxStringElements = 1000 // no need to mkString billions of elements
Mais je ne vais pas essayer des milliards:
scala> Array.tabulate(100)(identity)
res5: Array[Int] = Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99)
scala> import runtime.ScalaRunTime.replStringOf
import runtime.ScalaRunTime.replStringOf
scala> replStringOf(res5, 10)
res6: String =
"Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
"
scala> res5.take(10).mkString(", ")
res7: String = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
Attendez, faisons ça:
scala> res5.take(10).mkString("Array(", ", ", ")")
res8: String = Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
Cela pourrait être évident:
scala> var vs = List("1")
vs: List[String] = List(1)
scala> vs = null
vs: List[String] = null
scala> vs.mkString
Java.lang.NullPointerException
Donc au lieu:
scala> import runtime.ScalaRunTime.stringOf
import runtime.ScalaRunTime.stringOf
scala> stringOf(vs)
res16: String = null
De plus, un tableau n'a pas besoin d'être profond pour bénéficier de son stringPrefix:
scala> println(res0.deep.toString)
Array(bob, sue)
Quelle que soit la méthode que vous préférez, vous pouvez envelopper:
implicit class MkLines(val t: TraversableOnce[_]) extends AnyVal {
def mkLines: String = t.mkString("", EOL, EOL)
def mkLines(header: String, indented: Boolean = false, embraced: Boolean = false): String = {
val space = "\u0020"
val sep = if (indented) EOL + space * 2 else EOL
val (lbrace, rbrace) = if (embraced) (space + "{", EOL + "}") else ("", "")
t.mkString(header + lbrace + sep, sep, rbrace + EOL)
}
}
Mais les tableaux nécessiteront une conversion spéciale car vous n'obtiendrez pas le paramètre ArrayOps:
implicit class MkArrayLines(val a: Array[_]) extends AnyVal {
def asTO: TraversableOnce[_] = a
def mkLines: String = asTO.mkLines
def mkLines(header: String = "Array", indented: Boolean = false, embraced: Boolean = false): String =
asTO.mkLines(header, indented, embraced)
}
scala> Console println Array("bob","sue","zeke").mkLines(indented = true)
Array
bob
sue
zeke
Voici deux méthodes.
L'une consiste à utiliser foreach :
val a = Array(1,2,3)
a.foreach(println)
L'autre consiste à utiliser mkString :
val a = Array(1,2,3)
println(a.mkString(""))
Si vous utilisez plutôt list, la méthode toString()
affiche les éléments réels (pas le hashCode).
var a = List(1,2,3)
println(a)
ou
var a = Array(1,2,3)
println(a.toList)
Plutôt que de spécifier vous-même tous les paramètres pour mkString
(ce qui est un peu plus détaillé si vous souhaitez ajouter des marqueurs de début et de fin en plus du délimiteur), vous pouvez tirer parti de la classe WrappedArray
, qui utilise mkString
en interne . Contrairement à la conversion du tableau en une structure List
ou en une autre structure de données, la classe WrappedArray
encapsule simplement une référence de tableau, elle est créée avec un temps réellement constant.
scala> val a = Array.range(1, 10)
a: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9)
scala> println(a)
[I@64a2e69d
scala> println(x: Seq[_]) // implicit
WrappedArray(a, b, c, d)
scala> println(a.toSeq) // explicit
WrappedArray(1, 2, 3, 4, 5, 6, 7, 8, 9)
Pour un tableau simple d'Ints comme celui-ci, nous pouvons convertir en Scala List ( scala.collection.immutable.List
) puis utiliser List.toString()
:
var xs = Array(3,5,9,10,2,1)
println(xs.toList.toString)
// => List(3, 5, 9, 10, 2, 1)
println(xs.toList)
// => List(3, 5, 9, 10, 2, 1)
Si vous pouvez convertir une liste plus tôt et effectuer toutes vos opérations avec des listes, vous finirez probablement par écrire une version plus idiomatique de Scala, écrite dans un style fonctionnel.
Notez que l'utilisation de List.fromArray
est obsolète (et a été supprimée en 2.12.2)}.
La méthode deep
in ArrayLike
convertit récursivement des tableaux multidimensionnels en WrappedArray
et remplace un long préfixe "WrappedArray" par "Array".
def deep: scala.collection.IndexedSeq[Any] = new scala.collection.AbstractSeq[Any] with scala.collection.IndexedSeq[Any] {
def length = self.length
def apply(idx: Int): Any = self.apply(idx) match {
case x: AnyRef if x.getClass.isArray => WrappedArray.make(x).deep
case x => x
}
override def stringPrefix = "Array"
}
Usage:
scala> val arr = Array(Array(1,2,3),Array(4,5,6))
arr: Array[Array[Int]] = Array(Array(1, 2, 3), Array(4, 5, 6))
scala> println(arr.deep)
Array(Array(1, 2, 3), Array(4, 5, 6))