2017-06-22 66 views
0

假設我需要一個函數從字符串str過濾掉chars字符,然後從結果只拿k第一字符:如何一次處理懶惰的兩個字符串?

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

這個實現是不理想的,因爲它不必要地掃描整個字符串。爲了優化它,我們可以使用view或事件Stream掃描輸入懶洋洋地,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) 

現在假設我需要清理和修剪懶洋洋地字符串。我想fold他們懶惰地一次處理他們兩個單個字符並返回兩個結果。

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

你會如何建議實施它?

+0

你把兩個字符串過濾器他們並返回一個單一的字符串?你回來哪一個? –

+0

我的錯誤。我需要返回兩者。更新問題。 – Michael

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

他只需要該字符串的一定數量的字符。所以如果他有一串長度爲20的字符串,他只需要10(k),那麼他只需要掃描,直到他有10個字符,這些字符不在字符集中。儘管如此,你對第二個實現是正確的,但我認爲他只是忘了把'take(k)'放在最後(我在我的評論中指出)。 – thwiegan