web-dev-qa-db-fra.com

Tableau d'impression en Scala

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!

31
ivan_zd

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.

66
Rex Kerr

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
13
som-snytt

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(""))
8
Haimei

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)
2
Jiri Kremser

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)         
1
DaoWen

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)}.

0
James Lawson

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))
0
Yuichiroh