I have a use case where I need to return a String up to a delimiter String (if found) from an iterator of Char.
The contract:
- if iterator is exhausted (only at the begin), return None
- if the delimiter String is found, return all characters before it (empty String is fine), delimiter will be dropped
- else return the remaining characters
- do not eagerly exhaust the iterator!
I do have this working solution, but it feels like Java (which is where I'm coming from)
class MyClass(str: String) {
def nextString(iterator: Iterator[Char]): Option[String] = {
val sb = new StringBuilder
if(!iterator.hasNext) return None
while (iterator.hasNext) {
sb.append(iterator.next())
if (sb.endsWith(str)) return Some(sb.stripSuffix(str))
}
Some(sb.toString())
}
}
Is there a way I can do this in a more functional way (ideally without changing the method signature)?
Update: Here is how I test this
val desmurfer = new MyClass("_smurf_")
val iterator: Iterator[Char] = "Scala_smurf_is_smurf_great_smurf__smurf_".iterator
println(desmurfer.nextString(iterator))
println(desmurfer.nextString(iterator))
println(desmurfer.nextString(iterator))
println(desmurfer.nextString(iterator))
println(desmurfer.nextString(iterator))
println
println(desmurfer.nextString("FooBarBaz".iterator))
println(desmurfer.nextString("".iterator))
Output:
Some(Scala)
Some(is)
Some(great)
Some()
None
Some(FooBarBaz)
None