2013-07-13 97 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))