Splitting string into groups

后端 未结 9 980
再見小時候
再見小時候 2020-12-15 09:52

I\'m trying to \'group\' a string into segments, I guess this example would explain it more succintly

scala> val str: String = \"aaaabbcddeeeeeeffg\"
...          


        
9条回答
  •  爱一瞬间的悲伤
    2020-12-15 10:33

    Starting Scala 2.13, List is now provided with the unfold builder which can be combined with String::span:

    List.unfold("aaaabbaaacdeeffg") {
      case ""   => None
      case rest => Some(rest.span(_ == rest.head))
    }
    // List[String] = List("aaaa", "bb", "aaa", "c", "d", "ee", "ff", "g")
    

    or alternatively, coupled with Scala 2.13's Option#unless builder:

    List.unfold("aaaabbaaacdeeffg") {
      rest => Option.unless(rest.isEmpty)(rest.span(_ == rest.head))
    }
    // List[String] = List("aaaa", "bb", "aaa", "c", "d", "ee", "ff", "g")
    

    Details:

    • Unfold (def unfold[A, S](init: S)(f: (S) => Option[(A, S)]): List[A]) is based on an internal state (init) which is initialized in our case with "aaaabbaaacdeeffg".
    • For each iteration, we span (def span(p: (Char) => Boolean): (String, String)) this internal state in order to find the prefix containing the same symbol and produce a (String, String) tuple which contains the prefix and the rest of the string. span is very fortunate in this context as it produces exactly what unfold expects: a tuple containing the next element of the list and the new internal state.
    • The unfolding stops when the internal state is "" in which case we produce None as expected by unfold to exit.

提交回复
热议问题