问题
Suppose I need a function to filter out characters of chars
from a string str
and then take only k
first characters from the result:
def cleanTrim(str: String, chars: Set[Char], k: Int): String =
str.filterNot(chars).take(k)
This implementation is suboptimal since it needlessly scans the whole string. In order to optimize it we can use view
or event Stream
to scan the input lazily, e.g:
def cleanTrim(str: String, chars: Set[Char], k: Int): String =
str.view.foldLeft("") { case (r, c) => if (chars.contains(c)) r + c else r }.take(k)
Suppose now that I need to clean and trim lazily two strings. I would like to fold
them lazily to process a single character from both of them at once and return both results.
def cleanTrim2(str1: String,
str2: String,
chars: Set[Char],
k: Int): (String, String) = ???
How would you suggest implement it ?
回答1:
I do not see any gain of using laziness. In your second implementation of cleanTrim
you still scan whole string, actually you can't check if string contains
char without scanning whole string (or stream or view).
UPD: @thwiegan right, I didn't read the question carefully.
UPD2: Ok, my second try, don't know if it is important for you to use fold
, but I see the way to make it more clear:
def cleanTrim2(str1: String, str2: String, chars: Set[Char], k: Int): (String, String) = {
val result1 = str1.iterator.filterNot(chars).take(k).mkString
val result2 = str2.iterator.filterNot(chars).take(k).mkString
(result1, result2)
}
来源:https://stackoverflow.com/questions/44699776/how-to-process-lazily-two-strings-at-once