问题
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