I'm looking for a Scala implementation of Haskell's groupBy.
The behavior should be like this:
isD :: Char -> Bool
isD c = elem c "123456789-_ "
groupBy (\a b -> isD a == isD b) "this is a line with 0123344334343434343434-343 3345"
["this"," ","is"," ","a"," ","line"," ","with"," 0123344334343434343434-343 3345"]
I tried the Scala groupBy function, however it only takes a function of one argument, instead of Haskell's 2. I also looked at partition, however it only returns a tuple.
The function I'm looking for should group each consecutive element matching a predicate.
Questions like this seem to come up quite often, which is a good indication IMO that Rex Kerr's groupedWhile
method should be included in the standard collections library. However if you don't want to copy / paste that into your project...
I like your recursive solution, but it doesn't actually output the right thing (i.e. Strings), so here's how I'd change it:
def groupBy(s: String)(f: (Char, Char) => Boolean): List[String] = s match {
case "" => Nil
case x =>
val (same, rest) = x span (i => f(x.head, i))
same :: groupBy(rest)(f)
}
Then, take your function and try it in the REPL:
val isD = (x: Char) => "123456789-_ " contains x
groupBy("this is a line with 0123344334343434343434-343 3345")(isD(_) == isD(_))
The result is a List[String]
, which is presumably what you really wanted.
Used this for now, thanks to the answers:
def groupByS(eq: (Char,Char) => Boolean, list: List[Char]): List[List[Char]] = {
list match {
case head :: tail => {
val newHead = head :: tail.takeWhile(eq(head,_))
newHead :: groupByS(eq, tail.dropWhile(eq(head,_)))
}
case nil => List.empty
}
}
this can probably be improved upon ;)
It's surely can't be too difficult to translate the Haskell version into Scala. Here's the Haskell definition of groupBy
. It uses span
; I don't know offhand whether there's an equivalent to span
in Scala or whether you'll need to translate the Haskell definition of span
as well.
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