将 For 循环转换为折叠

Converting a For Loop to a Fold

我必须分析一个电子邮件语料库,看看有多少单独的句子以 leet speak(即 lol、brb 等)为主

对于每个句子我都在做以下事情:

   val words = sentence.split(" ")

    for (word <- words) {
      if (validWords.contains(word)) {
        score += 1
      } else if (leetWords.contains(word)) {
        score -= 1
      }
    }

有没有更好的使用Fold计算分数的方法?

这是一种使用折叠和部分应用的方法。还可以更优雅,我会继续思考

val sentence = // ...your data....
val validWords = // ... your valid words...
val leetWords = // ... your leet words...

def checkWord(goodList: List[String], badList: List[String])(c: Int, w: String): Int = {
  if (goodList.contains(w)) c + 1
  else if (badList.contains(w)) c - 1
  else c
}

val count = sentence.split(" ").foldLeft(0)(checkWord(validWords, leetWords))
print(count)

差别不大,但有另一种选择。

val words = List("one", "two", "three")
val valid = List("one", "two")
val leet = List("three")

def check(valid: List[String], invalid: List[String])(words:List[String]): Int = words.foldLeft(0){
  case (x, word) if valid.contains(word) => x + 1
  case (x, word) if invalid.contains(word) => x - 1
  case (x, _ ) => x
}

val checkValidOrLeet = check(valid, leet)(_)
val count = checkValidOrLeet(words)

如果不限于fold,用sum会更简洁

sentence.split(" ")
  .iterator
  .map(word =>
    if (validWords.contains(word)) 1
    else if (leetWords.contains(word)) -1
    else 0
  ).sum