List
对象具有mkString
方法,该方法可以转换为带分隔符的字符串。但是,大多数人类语言在枚举列表时会将最后一个元素视为不同。例如A,B,C和D.
在代码大小和合理效率方面,最好的是什么?确切地说,我正在寻找满足以下条件的函数:
assertEquals("",foo(List()))
assertEquals("A",foo(List("A")))
assertEquals("A and B",foo("List("A","B")))
assertEquals("A, B and C", foo(List("A","B","C")))
assertEquals("A, B, C and D", foo(List("A","B","C","D")))
答案 0 :(得分:9)
def foo(xs: List[String]) =
(xs.dropRight(2) :\ xs.takeRight(2).mkString(" and "))(_+", "+_)
编辑:这可能会更清楚一点:
def foo(xs: List[String]) =
(xs.dropRight(2) :+ xs.takeRight(2).mkString(" and ")).mkString(", ")
@axaluss速度取决于列表长度。平均列表长度大约超过4个元素,第二个版本比Tomasz更快。否则,它会稍微慢一些。
答案 1 :(得分:8)
我的看法:
def foo[T](list: List[T]): String = list match {
case Nil => ""
case x :: Nil => x.toString
case x :: y :: Nil => x + " and " + y
case x :: rs => x + ", " + foo(rs)
}
还要利用尾递归:
@tailrec def str[T](cur: String, list: List[T]): String = list match {
case Nil => cur
case x :: Nil => cur + x
case x :: y :: Nil => cur + x + " and " + y
case x :: rs => str(cur + x + ", ", rs)
}
def foo[T](list: List[T]) = str("", list)
答案 2 :(得分:4)
def foo(list: List[String]) = list match{
case Nil => ""
case _ if list.length == 1 => list.first
case _ => list.init.mkString(", ") + " and " + list.last
}