2011-08-22 32 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。

相关问题