严格来说如何格式化该代码,而不进行任何结构更改,我会这样做:
Console println (
(
io.Source
fromFile "names.txt"
getLines ()
mkString ""
split ","
map (x => x.slice(1, x.length - 1))
sortBy (x => x)
zipWithIndex
)
map (t => (t._2 + 1) * (t._1 map (_.toChar - "A"(0).toChar + 1) sum) )
sum
)
或者,也许,为了绕过无参数方法,我会这样做:
Console println (
io.Source
.fromFile("names.txt")
.getLines
.mkString
.split(",")
.map(x => x.slice(1, x.length - 1))
.sortBy(x => x)
.zipWithIndex
.map(t => (t._2 + 1) * (t._1 map (_.toChar - "A"(0).toChar + 1) sum) )
.sum
)
请注意,cmets 有足够的空间,但是,一般来说,什么
正在做的事情通常很清楚。不习惯的人有时会迷路
中途,没有变量来跟踪的含义/类型
转换后的值。
现在,我会做一些不同的事情:
println ( // instead of Console println
Source // put import elsewhere
.fromFile("names.txt")
.mkString // Unless you want to get rid of /n, which is unnecessary here
.split(",")
.map(x => x.slice(1, x.length - 1))
.sorted // instead of sortBy
.zipWithIndex
.map { // use { only for multiple statements and, as in this case, pattern matching
case (c, index) => (index + 1) * (c map (_ - 'A' + 1) sum) // chars are chars
}
.sum
)
我也不会在同一步骤中进行求和和乘法,所以:
.sorted
.map(_ map (_ - 'A' + 1) sum)
.zipWithIndex
.map { case (av, index) => av * (index + 1) }
.sum
最后,我不太喜欢调整字符串大小,所以我可能会求助于正则表达式。添加一点重构,这就是我可能会写的东西:
import scala.io.Source
def names = Source fromFile "names.txt" mkString
def wordExtractor = """"(.*?)"""".r
def words = for {
m <- wordExtractor findAllIn names matchData
} yield m group 1
def alphabeticValue(s: String) = s map (_ - 'A' + 1) sum
def wordsAV = words.toList.sorted map alphabeticValue
def multByIndex(t: (Int, Int)) = t match {
case (av, index) => av * (index + 1)
}
def wordsAVByIndex = wordsAV.zipWithIndex map multByIndex
println(wordsAVByIndex.sum)
编辑
下一步将是重命名重构——选择能够更好地传达代码各部分功能的名称。 Ken 建议在 cmets 中使用更好的名称,我会将它们用于另一种变体(它还很好地展示了 更好的 命名在多大程度上提高了可读性)。
import scala.io.Source
def rawData = Source fromFile "names.txt" mkString
// I'd rather write "match" than "m" in the next snippet, but
// the former is a keyword in Scala, so "m" has become more
// common in my code than "i". Also, make the return type of
// getWordsOf clear, because iterators can be tricky.
// Returning a list, however, makes a much less cleaner
// definition.
def wordExtractor = """"(.*?)"""".r
def getWordsOf(input: String): Iterator[String] = for {
m <- wordExtractor findAllIn input matchData
} yield m group 1
def wordList = getWordsOf(rawData).toList
// I stole letterPosition from Kevin's solution. There, I said it. :-)
def letterPosition(c: Char) = c.toUpper - 'A' + 1 // .toUpper isn't necessary
def alphabeticValueOfWord(word: String) = word map letterPosition sum
def alphabeticValues = wordList.sorted map alphabeticValueOfWord
// I don't like multAVByIndex, but I haven't decided on a better
// option yet. I'm not very fond of declaring methods that return
// functions either, but I find that better than explicitly handling
// tuples (oh, for the day tuples/arguments are unified!).
def multAVByIndex = (alphabeticValue: Int, index: Int) =>
alphabeticValue * (index + 1)
def scores = alphabeticValues.zipWithIndex map multAVByIndex.tupled
println(scores sum)