splitAt '-' in scala

3.7k Views Asked by At

I need to return two lists, the list of Strings up to and including the first line containing a ’-’ and then the remaining elements.

so i've been trying lst.splitAt('-') but it keeps doing

 scala> val lst = List(" Hi this is - a test")
 lst: List[String] = List(" Hi this is - a test")

 scala> lst.splitAt('-')
 res8: (List[String], List[String]) = (List(" Hi this is - a test"),List())

how can i fix this so that i will get (List(" Hi this is -),List( a test")) ?

2

There are 2 best solutions below

2
On BEST ANSWER

The argument to List's splitAt is an Int. your '-' is being coerced to 45 and trying to split the list at index 45.

You can do this for a single string:

"hello-test-string".split('-')

The result of this (in sbt) is:

res0: Array[String] = Array(hello, test, string)

You can map this function over a list of strings if you want:

List("hello-test-string", "some-other-cool-string").map(_.split('-').toList)

The result of this is:

res1: List[List[String]] = List(List(hello, test, string), List(some, other, cool, string))
1
On

Consider span together with unzip like this,

lst.map(_.span(_ != '-')).unzip

which delivers

(List(" Hi this is "),List("- a test"))

Note that span bisects a collection (in this case each string in the list) up to the first element that does not hold a condition (equality to '-' here).

Update

For including the '-' char, we may define a takeUntil method on strings, for instance as follows,

implicit class StringFetch(val s: String) extends AnyVal {
  def takeUntil(p: Char => Boolean) = {
    val (l,r) = s.span(p)
    val (rl,rr) = r.span(!p(_))
    l + rl
  }
}

Hence

lst.map(_.takeUntil(_!= '-'))
res: List[String] = List(" Hi this is -")