2013-07-13 118 views
25

我遇到了大多數基本Scala操作的問題,它讓我發瘋。在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] 

誰能告訴我如何在沒有編寫自己的函數的情況下打印數組,因爲這很愚蠢。謝謝!

+0

嘗試在Java中類似的代碼,你會看到,它做同樣的事情。 'T []。toString()'不返回包含數組元素的String。 – Jashaszun

+0

我在java中有點生疏:D ...所以,你說沒有打印數組的解決方案,但是自己寫函數? ... –

+0

dupe http://stackoverflow.com/questions/3328085/scala-printing-arrays和其他人 –

回答

55

mkString會將集合(包括Array)逐個元素轉換爲字符串表示形式。

println(a.mkString(" ")) 

可能是你想要的。

+1

是的,這絕對是更好的解決方案.. – Hassan

+0

就是這樣! ...非常感謝:)我知道必須有一些正常的解決方案。 –

2

如果使用列表,而不是,toString()方法打印的實際elenents(未哈希碼)

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

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

你可以做正常的事情(見無論是Rex的或吉日的答案) ,或者你可以:

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

嘿,不公平! REPL印出來真的很棒。

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

沒有喜悅,直到:

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

我不知道是否有在REPL寬度設置。更新:沒有。它固定在

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

但我不會嘗試十億:

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 

等待,讓我們做的是:

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

這可能是顯而易見的:

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

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

scala> vs.mkString 
java.lang.NullPointerException 

所以相反:

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

scala> stringOf(vs) 
res16: String = null 

而且,陣列不需要深從其stringPrefix受益:

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

你更喜歡哪一種方法,你可以用它:

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

但陣列將需要特殊轉換,因爲您沒有獲得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

,而不是手動指定所有參數都mkString自己(這是更詳細一點,如果你想在除了分隔符添加開始和結束標記),你可以採取WrappedArray類的優勢,which uses mkString internally。與將數組轉換爲List或其他某種數據結構不同,WrappedArray類只是包裝數組引用,它的創建時間是有效的。

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

這裏有兩種方法。

一種是使用的foreach

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

另一種方法是使用mkString

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

對於大數組的每個更好的答案。 – tgkprog

0

對於這樣INTS的簡單數組,我們可以轉換爲斯卡拉列表scala.collection.immutable.List)然後使用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) 

如果你以前可以轉換爲列表並且使用列表完成所有的操作,那麼你最終可能會寫出更多慣用的Scala,寫成功能風格。

注意,使用List.fromArray被棄用(和2.12.2中已被刪除)

0

方法deep in ArrayLike遞歸地將多維數組轉換爲WrappedArray,並用「Array」覆蓋長前綴「WrappedArray」。

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

用法:

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