Это хороший стиль, чтобы гнездиться для понимания в Scala? - PullRequest
3 голосов
/ 23 августа 2011

Я только что обнаружил, что пишу кусок кода, который выглядит следующим образом:

  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 представляет собой массив значений типа Double, созданный из массива строк. Работает нормально. Я просто раньше не видел, чтобы такие понимания были вложенными. Это нормально или я должен как-то рефакториться?

Ответы [ 2 ]

7 голосов
/ 23 августа 2011

Обычно более стандартно использовать 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? Это кажется странным.)

0 голосов
/ 23 августа 2011

Как только я использую оператор сопоставления или что-то другое, то просто, просто, если / иначе я бы использовал там метод. При хорошем названии код станет более понятным для чтения IMO.

...