2011-08-22 36 views
3

我只是發現自己編寫了一段代碼,看起來像這樣:在Scala中嵌套理解是否是一種很好的風格?

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是一個字符串數組創建雙打的數組。它工作正常。我以前沒有看到過這樣嵌套的理解。它可以或者我應該重構嗎?

+3

我認爲沒關係。我更害怕地圖陣列。 –

+0

@ om-nom-nom我已經改變了一下,所以沒有更多的地圖數組!無論如何感謝評論。 –

回答

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(我==)是非零,但fset.indexOf(i)是-1?這似乎很奇怪)。

+0

謝謝!我之前沒有在'lambda'裏看到'val's ...需要重新調整大腦。我建議你在開始的時候原本是字母數字,這顯然更好,但只是因爲它更簡潔(可能是一個不好的理由)而將它放在了理解之中。如果字母不在頻率表中,平方位是可以的,因爲我們希望隱含字母爲零。如果你想知道這是我對TopCoder問題的解決方案(TCHS1,500分)。 –

0

只要我使用匹配語句或其他簡單的東西,如果/ else我會使用一個方法。通過良好的命名代碼會更清晰地讀取IMO。

相關問題