3

我刚刚发现自己编写了一段代码,如下所示:

  def language(frequencies: Array[String], text: Array[String]) = {
    val allText = text.mkString.replace(" ", "")

    val emaps = for {
      fset <- frequencies
      devs = for {
        i <- 'a' to 'z'
        p = fset.indexOf(i) match {
          case -1 => 0d
          case x  => fset.substring(x + 1, x + 3).toDouble / 100 * allText.size
        }
        a = allText.count(i ==)
        dev = math.pow(p - a, 2)
      } yield dev
    } yield devs.sum

    emaps.min
  }

如您所见,该值emaps是从字符串数组创建的双精度数组。它工作正常。我只是以前没有见过像这样嵌套的理解。可以吗,还是我应该以某种方式重构?

4

2 回答 2

7

它通常map比在 for 结构的循环部分编写长代码块更标准。由于 allText 不依赖于频率,因此您可以在开始时执行一次:

val lcounts = 'a' to 'z' map {i => i -> allText.count(i==)} toMap
val emaps = frequencies.map { fset =>
  val devs = 'a' to 'z' map { i =>
    val p = fset.indexOf(i) match {
      case -1 => 0d
      case x  => fset.substring(x+1, x+3).toDouble / 100 * allText.size
    }
    math.pow(p - lcounts(i), 2)
  }
  devs.sum
}

(另外,您确定要对负值求平方,即 allText.count(i==) 不为零,但 fset.indexOf(i) 为-1?这看起来很奇怪。)

于 2011-08-23T02:25:17.573 回答
0

一旦我使用匹配语句或其他简单的东西,如果/否则我会在那里使用一种方法。通过良好的命名,代码将变得更清晰易读 IMO。

于 2011-08-23T06:28:26.907 回答