Scala:使用输出流时的打印分隔符

Scala:使用输出流时的打印分隔符,scala,Scala,当需要连接字符串数组时,可以使用mkString方法: val concatenatedString = listOfString.mkString 然而,当我们有一个很长的字符串列表时,获取连接的字符串可能不是一个好的选择。在这种情况下,更适合直接打印到输出流,将其写入输出流很简单: listOfString.foreach(outstream.write _) 然而,我不知道一种添加分隔符的好方法。我尝试过的一件事是使用索引循环: var i = 0 for(str <- list

当需要连接字符串数组时,可以使用mkString方法:

val concatenatedString = listOfString.mkString
然而,当我们有一个很长的字符串列表时,获取连接的字符串可能不是一个好的选择。在这种情况下,更适合直接打印到输出流,将其写入输出流很简单:

listOfString.foreach(outstream.write _)
然而,我不知道一种添加分隔符的好方法。我尝试过的一件事是使用索引循环:

var i = 0
for(str <- listOfString) {
  if(i != 0) outstream.write ", "
  outstream.write str
  i += 1
}
这行得通,但太罗嗦了。虽然我可以让一个函数封装上面的代码,但我想知道Scala API是否已经有一个函数可以做同样的事情


谢谢。

我相信您需要的是mkString的重载定义

mkString的定义:

def mkString:String

def mkStringsep:String:String

def mkStringstart:String、sep:String、end:String:String

编辑 这个怎么样

scala> strList.view.map(_ + ", ").foreach(print) // or .iterator.map
hello, world, this, is, bob,

下面是一个函数,它以更优雅的方式实现了您想要的功能:

def commaSeparated(list: List[String]): Unit = list match {
    case List() => 
    case List(a) => print(a)
    case h::t => print(h + ", ")
                 commaSeparated(t)
}
递归避免了可变变量

为了使其更具功能性,您可以传入要在每个项目上使用的函数,即:

def commaSeparated(list: List[String], func: String=>Unit): Unit = list match {
    case List() => 
    case List(a) => func(a)
    case h::t => func(h + ", ")
                 commaSeparated(t, func)
}
然后通过以下方式调用:

commaSeparated(mylist, oustream.write _)
自我回答:

我在原始问题中编写了一个函数来封装代码:

implicit def withSeparator[S >: String](seq: Seq[S]) = new {
  def withSeparator(write: S => Any, sep: String = ",") = {
    var i = 0
    for (str <- seq) {
      if (i != 0) write(sep)
      write(str)
      i += 1
    }
    seq
  }
}
也可以指定分隔符:

listOfString.withSeparator(print _, ",\n")

谢谢大家回答我。我想使用的是一个简洁而不太慢的表示法。带separator的隐式函数看起来就像我想要的一样。所以我接受我自己对这个问题的回答。再次感谢您。

不适合并行化代码,但除此之外:

val it = listOfString.iterator
it.foreach{x => print(x); if (it.hasNext) print(' ')}

下面是另一种避免var的方法

listOfString.zipWithIndex.foreach{ case (s, i) =>
    if (i != 0) outstream write ","
    outstream write s }

还有,有时候,使用mkStringfirstDel,del,lastDelNo是很有用的,我要做的是直接写入输出流,而不是得到连接的字符串,因为我有很长的列表要连接。编辑,这就是你想要的吗?谢谢,但是拖尾额外的逗号,会给某些上下文带来问题。是的,这就是我在最初的问题中所做的。我想问的是开箱即用的函数在一行中完成这项工作。
implicit def withSeparator[S >: String](seq: Seq[S]) = new {
  def withSeparator(write: S => Any, sep: String = ",") = {
    var i = 0
    for (str <- seq) {
      if (i != 0) write(sep)
      write(str)
      i += 1
    }
    seq
  }
}
listOfString.withSeparator(print _)
listOfString.withSeparator(print _, ",\n")
val it = listOfString.iterator
it.foreach{x => print(x); if (it.hasNext) print(' ')}
listOfString.zipWithIndex.foreach{ case (s, i) =>
    if (i != 0) outstream write ","
    outstream write s }