我想写一个函数,功能很简单,如下:把一个字符串里的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
这个功能用C写很简单,而且近乎是最优化的代码
char *Fun(char *str)
{
for(;*str;++str)
if(‘b’ == *str)
*str = ‘*’;
if(‘c’ == *(str-1))
*(str-1) = ‘#’;
}