Freewind @ Thoughtworks scala java javascript dart 工具 编程实践 月结 math python english [comments admin] [feed]

(2011-09-13) 一个函数的优化(从命令式到函数式)

广告: 云梯:翻墙vpn (省10元) 土行孙:科研用户翻墙http proxy (有优惠)

我想写一个函数,功能很简单,如下:把一个字符串里的b改为*,把结尾的c改为#。代码如下:

object Main {
    def fix(text: String) = {
        val s = text.replace("b", "*")
        if (s.endsWith("c")) {
            s.stripSuffix("c") + ("#")
        } else s
    }
    def main(args: Array[String]) {
        println(fix("abbbbccc")) // -> a***cc#
    }
}

可以看出,还是在用java的方式来写,总觉得不够scala。应该怎么优化呢?

首先,要转变思想,多使用正则表达式:

def fix(s: String) = s.replace('b', '*').replaceAll("c$", "#")

一行就搞定。

如果我们不想定义那个变量s,希望使用链式风格,可以使用Some,如下:

def fix(s: String) = Some(s.replace('b', '*')).map(s => if(s.endsWith("c")) s.init + "#" else s).get

还是一行。

最后,我们还有一个match可用:

text.replace("b", "*") match {
   case t if t.endsWith("c") => t.stripSuffix("c") + "#"
   case t => t
}

函数式的风格写起来就是很爽,如行云流水一般。从java到scala,不仅仅是语法变了,更重要的是编程的风格,这个转变可不容易。

我在stackoverflow上问了这个问题,请参见完整版:

http://stackoverflow.com/questions/5140465/how-to-optimize-this-simple-function-in-scala

一些评论

htrmt

这个功能用C写很简单,而且近乎是最优化的代码

char *Fun(char *str)
{
  for(;*str;++str)
    if(‘b’ == *str)
      *str = ‘*’;
  if(‘c’ == *(str-1))
    *(str-1) = ‘#’;
}
comments powered by Disqus