如何一次懒惰地处理两个字符串? [英] How to process lazily two strings at once?

查看:74
本文介绍了如何一次懒惰地处理两个字符串?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我需要一个函数来从字符串str中过滤出chars字符,然后从结果中仅提取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) = ???

您如何建议实施?

解决方案

我看不到使用惰性的任何好处.在cleanTrim的第二种实现中,您仍然会扫描整个字符串,实际上,如果不扫描整个字符串(或流或视图),就无法检查字符串contains char是否为.

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

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 ?

解决方案

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

这篇关于如何一次懒惰地处理两个字符串?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆