这一个班轮…
Console.println(io.source.fromFile("names.txt").getLines.mkString.split(",").map{x:String => 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);
…是我的解决方案Project Euler problem 22.它似乎工作,它写在(我的尝试)的功能风格.
这个例子有点极端,但是我的问题比较笼统 – 你最喜欢写/格式/评论功能样式代码?功能性方法似乎鼓励了一系列方法调用,我发现这可能会变得不可读,也没有任何明显的意见.
此外,当我编写程序代码时,我发现我写了一些方法,每个方法有一个目的和有意义的名称.当我编写功能代码时,我似乎正在开发一种习惯,生成一条像上面那样的线条,其中(对我来说)意义难以破译 – 而且个别的计算也难以在其他地方重新使用.在网上看到的功能代码很多很简单(对我来说)模糊不清.
我该怎么办?为计算的每个部分编写一些功能,名称在当前上下文中有意义? (即使他们只是一个地图的包装,比如说?)
对于我给出的例子,什么是更好的写作方式,并展示它?
(像所有的风格问题,这个都是主观的,但是没有理由应该得到论证!)
解决方法
一个微不足道的首次尝试整理它只是删除领先的控制台.尾随和explicit:String类型 – 所有这些都是不必要的 – 添加一些缩进并导入io.source:
import io.source println( 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 )
下一步是清理一下,使用模式匹配来映射元组列表和身份而不是x => x. tochar对于字符也是不必要的,单引号可用于表示字符文字.
import io.source println( Source.fromFile("names.txt").getLines.mkString.split(",").map { x => x.slice(1,x.length -1) }.sortBy(identity).zipwithIndex.map { case (v,idx) =>{ (idx+1)*(v.map{_ - 'A' + 1}.sum)} }.sum )
还有一些更改也有助于使代码的意图更清晰:
import io.source println( Source.fromFile("names.txt").getLines.mkString.split(",") .map { _.stripPrefix("\"").stripSuffix("\"") } .sortBy(identity) .map { _.map{_ - 'A' + 1}.sum } .zipwithIndex .map { case (v,idx) => (idx+1) * v } .sum )
下一步,使它更“功能”,就是将其分解为“功能”(偷偷摸摸,是吗?)理想情况下,每个功能都将有一个清楚表达其目的的名称,它将很短(旨在使其成为一个单一表达式,因此不需要大括号):
import io.source def unquote(s:String) = s.stripPrefix("\"").stripSuffix("\"") def wordsFrom(fname:String) = Source.fromFile(fname).getLines.mkString.split(",").map(unquote) def letterPos(c:Char) = c - 'A' + 1 println( wordsFrom("names.txt") .sortBy(identity) .map { _.map(letterPos).sum } .zipwithIndex .map { case (v,idx) => (idx+1) * v } .sum )