The List
object has the mkString
method that will can convert to a string with a seperator. However most human languages treats the last element different when enumerating a list. For example A, B, C and D.
What is the best in terms of code size and reasonable efficiency to accomplish this? To be precise, I am searching for a function that satisfies:
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")))
def foo(xs: List[String]) =
(xs.dropRight(2) :\ xs.takeRight(2).mkString(" and "))(_+", "+_)
edit: This might be a bit clearer:
def foo(xs: List[String]) =
(xs.dropRight(2) :+ xs.takeRight(2).mkString(" and ")).mkString(", ")
@axaluss The speed depends on the list length. With an average list length above about 4 elements, this second version is faster than Tomasz's. Otherwise, it's slightly slower.
My take:
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)
}
Also to utilize tail recursion:
@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)
def foo(list: List[String]) = list match{
case Nil => ""
case _ if list.length == 1 => list.first
case _ => list.init.mkString(", ") + " and " + list.last
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With