2011-03-01 61 views
3

目标:写,其生成一个新的字符串的功能不包括指定的字符(由索引标识)为什么斯卡拉抱怨时,这种模式匹配的整数值?

  • takeAllExcept(0, "abc")返回bc
  • takeAllExcept(1, "abc")返回ac
  • takeAllExcept(2, "abc")返回ab

我所做的最初

def takeAllExcept(index: Int, s: String): String = { 
    val lastIndex = s.length()-1 
    index match { 
    case 0 => return s.slice(1, s.length) 
    case lastIndex => return s.slice(0, s.length()-1) 
    case _ => { s.slice(0, index) + s.slice(index+1, s.length) } 
    } 
} 

编译器会抱怨,对于case _语句块不可达。

我如何固定它

def takeAllExcept(index: Int, s: String): String = { 
    val lastIndex = s.length()-1 
    if(index == 0) 
    return s.slice(1, s.length) 

    if(index == lastIndex) 
    return s.slice(0, s.length()-1) 

    s.slice(0, index) + s.slice(index+1, s.length) 
} 

我想知道为什么我的初步尝试用不到的代码失败。它看起来对我来说合法。另外,scala中是否有内置的工具已经这样做?

+1

不'情况lastIndex'创造的,而不是匹配现有变量值的*新的变量*用相同的名字,? – dave4420 2011-03-01 11:24:43

+1

模式匹配变量,在反引号中使用其名称 – coubeatczech 2011-03-01 11:56:23

+0

它与小写变量名称有关。改用'LastIndex'。海事组织,小写“功能”是一个很大的错误。 – Jus12 2011-03-02 04:03:16

回答

10

lastIndex的格局是必然的任何值放入比赛和阴影的媒体链接定义lastIndex新名称的隐式声明,其他两个职位媒体链接指出。还有其他两种可能性,而不是使用大写字母标识符(见彼得后):

使用反引号让编译器知道,这不应是一个新的标识符的声明:

case `lastIndex` => ... 

使用模式卫士:

case x if x == lastIndex => ... 

如果你想要做很多的取消对串话会更快通过调用字符串toBuffer使用一个缓冲区,然后你可以使用缓存的remove(i: Int)方法基于索引的。对于只有一个操作来说这比较慢,因为当你完成操作时你必须将缓冲区转换回字符串,但是如果你做了很多随机访问操作,速度要快得多。完成之后,您可以在缓冲区上拨打mkString以使您的字符串恢复。对于单去除我会做像彼得建议或这里是一个另类:

def takeAllExcept(i: Int, s: String) = s.take(i) + s.drop(i+1) 
6

你的第一个问题:

def takeAllExcept(index: Int, s: String): String = { 
    val LastIndex = s.length()-1 
    index match { 
    case 0 => return s.slice(1, s.length) 
    case LastIndex => return s.slice(0, s.length()-1) 
    case _ => { s.slice(0, index) + s.slice(index+1, s.length) } 
    } 
} 

lastIndexcase后新绑定的,而模式匹配和隐藏的val lastIndex = s.length()-1定义。如我的示例所示,您可以使用大写名称,然后scala使用范围中定义的val

要回答你的第二个问题,在某种程度上,我会解决这个问题:

def takeAllExcept(i: Int, s: String): String = { 
    val (prefix,suffix) = s.splitAt(i) 
    prefix + suffix.tail 
} 
+0

你的解决方案是邪恶的。我如何变得和你一样聪明? :) – 2011-03-01 13:06:46

+2

这很容易:阅读“Scala编程”书籍,自己做一些项目,阅读许多博客和stackoverflow条目,并永不停止尝试疯狂的方法;) – 2011-03-01 15:08:16

+0

Peter的解决方案将在'suffix.tail'如果你提供'i> = s.length'。然而,我的解决方案(可能效率不高)将是:'def takeAllExcept(i:Int,s:String)= s.zipWithIndex.filterNot(_._ 2 == i).map(_._ 1).mkString ' – 2011-03-01 18:40:22

1
val lastIndex = s.length()-1 
index match { 
    case 0 => return s.slice(1, s.length) 
    case lastIndex => return s.slice(0, s.length()-1) 
    case _ => { s.slice(0, index) + s.slice(index+1, s.length) } 
} 

第二条不尝试匹配indexlastIndex,你会从预期例如序言。相反,它会匹配任何值并将该值绑定到名称lastIndex,从而映射此变量的上一个绑定。