2013-07-13 17 views
25

Ho problemi con la maggior parte delle operazioni di base di Scala e mi sta facendo impazzire.Stampa array in Scala

val a = Array(1,2,3) 

println(a) and result is [[email protected] 

println(a.toString()) and result is [[email protected] 

println(a.toString) and result is [[email protected] 

Qualcuno può dirmi come stampare array senza scrivere il mio propria funzione per farlo, perché questo è stupido. Grazie!

+0

Prova codice simile a Java e vedrete che fa la stessa cosa. 'T []. ToString()' non restituisce un 'String' contenente gli elementi dell'array. – Jashaszun

+0

Sono un po 'arrugginito in java: D ... quindi, stai dicendo che non esiste una soluzione per la stampa di array ma la funzione di scrittura da solo? ... –

+0

dupe di http://stackoverflow.com/questions/3328085/scala-printing-arrays e altri –

risposta

55

mkString convertirà le raccolte (incluso Array) elemento per elemento alle rappresentazioni di stringa.

println(a.mkString(" ")) 

è probabilmente quello che desideri.

+1

Sì, questa è sicuramente la soluzione migliore .. – Hassan

+0

questo è tutto! ... grazie mille :) ... Sapevo che ci doveva essere una soluzione normale. –

2

Se si utilizza la lista invece, toString() metodo stampa i elenents effettivi (non il hashCode)

var a = List(1,2,3) 
println(a) 

o

var a = Array(1,2,3) 
println(a.toList) 
13

È possibile fare la cosa normale (vedere sia la risposta di Rex o Jiri di) , oppure è possibile:

scala> Array("bob","sue") 
res0: Array[String] = Array(bob, sue) 

Ehi, non è giusto! Il REPL lo ha stampato molto bello.

scala> res0.toString 
res1: String = [Ljava.lang.String;@63c58252 

Nessuna gioia, fino a quando:

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) 
" 

Mi chiedo se c'è un ambiente larghezza nella REPL. Aggiornamento: non c'è. E 'fissato a

val maxStringElements = 1000 // no need to mkString billions of elements 

Ma io non cercherà miliardi:

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 

Attendere, facciamo che:

scala> res5.take(10).mkString("Array(", ", ", ")") 
res8: String = Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) 

Questo potrebbe essere ovvio:

scala> var vs = List("1") 
vs: List[String] = List(1) 

scala> vs = null 
vs: List[String] = null 

scala> vs.mkString 
java.lang.NullPointerException 

Quindi, invece:

scala> import runtime.ScalaRunTime.stringOf 
import runtime.ScalaRunTime.stringOf 

scala> stringOf(vs) 
res16: String = null 

Inoltre, una serie non ha bisogno di essere profondo a beneficiare della sua stringprefix:

scala> println(res0.deep.toString) 
Array(bob, sue) 

Qualunque sia il metodo che preferite, si può avvolgere in su:

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

Ma array avrà bisogno di una conversione speciale perché non si ottiene l'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 
1

Invece di specificare manualmente tutti i parametri per mkString (che è un po 'più prolisso se si desidera aggiungere marcatori di inizio e fine oltre al delimitatore) è possibile usufruire della classe WrappedArray, which uses mkString internally.A differenza della conversione della matrice in una List o in un'altra struttura di dati, la classe WrappedArray racchiude semplicemente un riferimento di matrice, viene creata in un tempo effettivamente costante.

scala> val a = Array.range(1, 10)     
a: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9) 

scala> println(a)        
[[email protected]          

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)   
6

Qui ci sono due metodi.

Uno è quello di utilizzare foreach:

val a = Array(1,2,3) 
a.foreach(println) 

L'altro è quello di utilizzare mkString:

val a = Array(1,2,3) 
println(a.mkString("")) 
+0

Per ogni risposta migliore per un grande array. – tgkprog

0

Per una semplice matrice di INT come questo, siamo in grado di convertire in Scala Elenco (scala.collection.immutable.List) e quindi utilizzare 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) 

Se è possibile convertire in una lista in precedenza e fare tutte le operazioni con elenchi, probabilmente si finirà per scrivere Scala più idiomatica, scritta in uno stile funzionale.

noti che usare List.fromArray è obsoleto (ed è stato rimosso in 2.12.2).

0

Il metodo deep in ArrayLike converte in modo ricorsivo array multidimensionali in WrappedArray e sovrascrive un lungo prefisso "WrappedArray" con "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))