在 Scala 中打印数组

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17634427/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 05:29:43  来源:igfitidea点击:

Printing array in Scala

arraysscala

提问by Ivan Longin

I am having problem with most basic Scala operation and it is making me crazy.

我遇到了最基本的 Scala 操作问题,这让我很抓狂。

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

Can anyone tell me how to print array without writing my own function for doing that because that is silly. Thanks!

谁能告诉我如何在不编写自己的函数的情况下打印数组,因为这很愚蠢。谢谢!

回答by Rex Kerr

mkStringwill convert collections (including Array) element-by-element to string representations.

mkString将集合(包括Array)逐个元素转换为字符串表示形式。

println(a.mkString(" "))

is probably what you want.

可能是你想要的。

回答by som-snytt

You can do the normal thing (see either Rex's or Jiri's answer), or you can:

您可以做正常的事情(请参阅 Rex 或 Jiri 的回答),或者您可以:

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

Hey, no fair! The REPL printed it out real nice.

嘿,不公平!REPL 打印出来真的很好。

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

No joy, until:

没有快乐,直到:

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

I wonder if there's a width setting in the REPL. Update: there isn't. It's fixed at

我想知道 REPL 中是否有宽度设置。更新:没有。它固定在

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

But I won't try billions:

但我不会尝试数十亿:

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

Wait, let's make that:

等等,让我们这样做:

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

This might be obvious:

这可能很明显:

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

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

scala> vs.mkString
java.lang.NullPointerException

So instead:

所以与其:

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

scala> stringOf(vs)
res16: String = null

Also, an array doesn't need to be deep to benefit from its stringPrefix:

此外,数组不需要很深就可以从其 stringPrefix 中受益:

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

Whichever method you prefer, you can wrap it up:

无论您喜欢哪种方法,都可以将其包装起来:

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

But arrays will need a special conversion because you don't get the ArrayOps:

但是数组需要特殊的转换,因为你没有得到 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

回答by Haimei

Here are two methods.

这里有两种方法。

One is to use foreach:

一种是使用foreach

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

The other is to use mkString:

另一种是使用mkString

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

回答by Jiri Kremser

If you use list instead, toString()method prints the actual elenents (not the hashCode)

如果您改用 list,toString()方法将打印实际的元素(而不是 hashCode)

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

or

或者

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

回答by DaoWen

Rather than manually specifying all the parameters for mkStringyourself (which is a bit more verbose if you want to add start and end markers in addition to the delimiter) you can take advantage of the WrappedArrayclass, which uses mkStringinternally. Unlike converting the array to a Listor some other data structure, the WrappedArrayclass just wraps an array reference, it's created in effectively constant time.

而不是手动指定为所有参数mkString自己(这是一个比较详细的,如果你想在除了分隔符添加开始和结束标记),您可以采取的优势WrappedArray类,它使用mkString内部。与将数组转换为一个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)                               
[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)         

回答by James Lawson

For a simple Array of Ints like this, we can convert to a Scala List(scala.collection.immutable.List) and then use List.toString():

对于像这样的简单整数数组,我们可以转换为 Scala列表( 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)

If you can convert to a List earlier and do all your operations with Lists, then you'll probably end up writing more idiomatic Scala, written in a functional style.

如果您可以更早地转换为 List 并使用 Lists 执行所有操作,那么您最终可能会以函数式风格编写更惯用的 Scala。

Note that using List.fromArrayis deprecated (and has been removed in 2.12.2).

请注意, usingList.fromArray已弃用(并已在 2.12.2 中删除)

回答by Yuichiroh

The method deepin ArrayLikerecursively converts multidimensional arrays to WrappedArray, and overwrites a long prefix "WrappedArray" with "Array".

该方法deepArrayLike递归多维数组转换成WrappedArray,并覆盖一个长前缀“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"
}

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