如何一次懒洋洋地处理两个字符串?

时间:2017-06-22 12:43:54

标签: string scala stream lazy-evaluation

假设我需要一个函数来从字符串chars中过滤掉str的字符,然后从结果中只获取k个第一个字符:

def cleanTrim(str: String, chars: Set[Char], k: Int): String =
  str.filterNot(chars).take(k)

这种实现不是最理想的,因为它不必要地扫描整个字符串。为了优化它,我们可以使用view或事件Stream来懒惰地扫描输入,例如:

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)

现在假设我需要清理并修剪两个字符串。我想fold他们懒洋洋地同时处理他们两个人中的一个角色并返回两个结果。

def cleanTrim2(str1: String,
               str2: String,
               chars: Set[Char],
               k: Int): (String, String) = ???

你会如何建议实施它?

1 个答案:

答案 0 :(得分:3)

我没有看到使用懒惰的任何好处。在您的第二个cleanTrim实现中,您仍然扫描整个字符串,实际上您无法检查字符串contains是否不扫描整个字符串(或流或视图)。

UPD:@thwiegan对,我没有仔细阅读这个问题。

UPD2:好的,我的第二次尝试,不知道你使用fold是否重要,但我看到了让它更清晰的方法:

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)
    }