我是scala的新手,我只是编写一个简单的函数来反转给定的字符串:
def reverse(s: String) : String
for(i <- s.length - 1 to 0) yield s(i)
yield会返回一个scala.collection.immutable.IndexedSeq [Char],并且无法将其转换为String。 (或者是别的什么?)
我该如何写这个函数?
答案 0 :(得分:22)
请注意,已经定义了函数:
scala> val x = "scala is awesome"
x: java.lang.String = scala is awesome
scala> x.reverse
res1: String = emosewa si alacs
但如果你想自己这样做:
def reverse(s: String) : String =
(for(i <- s.length - 1 to 0 by -1) yield s(i)).mkString
或(有时候最好使用until
,但可能不是那种情况)
def reverse(s: String) : String =
(for(i <- s.length until 0 by -1) yield s(i-1)).mkString
另外,请注意,如果您使用反向计数(从较大的一个到较小的一个值),您应指定负步骤,否则您将得到一个空集:
scala> for(i <- x.length until 0) yield i
res2: scala.collection.immutable.IndexedSeq[Int] = Vector()
scala> for(i <- x.length until 0 by -1) yield i
res3: scala.collection.immutable.IndexedSeq[Int] = Vector(16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
答案 1 :(得分:11)
这是一个简短的版本
def reverse(s: String) = ("" /: s)((a, x) => x + a)
修改强> :或者甚至更短,我们有着神奇的神秘色彩
def reverse(s: String) = ("" /: s)(_.+:(_))
但我不会真的推荐这个...
答案 2 :(得分:8)
如om-nom-nom所示,请注意by -1
(否则你不是真的在迭代,你的结果将是空的)。您可以使用的另一个技巧是collection.breakOut
。
它也可以提供给for
这样的理解:
def reverse(s: String): String =
(for(i <- s.length - 1 to 0 by -1) yield s(i))(collection.breakOut)
reverse("foo")
// String = oof
使用breakOut
的好处是,它将避免像mkString
解决方案中那样创建中间结构。
注意:breakOut
正在利用CanBuildFrom
和构建器,这些构建器是scala 2.8.0中引入的重新设计的集合库的基础的一部分
答案 3 :(得分:8)
您也可以使用递归方法编写此内容(将此内容仅用于娱乐)
def reverse(s: String): String = {
if (s.isEmpty) ""
else reverse(s.tail) + s.head
}
答案 4 :(得分:3)
以上所有答案都是正确的,这是我的看法:
scala> val reverseString = (str: String) => str.foldLeft("")((accumulator, nextChar) => nextChar + accumulator)
reverseString: String => java.lang.String = <function1>
scala> reverseString.apply("qwerty")
res0: java.lang.String = ytrewq
答案 5 :(得分:0)
def rev(s: String): String = {
val str = s.toList
def f(s: List[Char], acc: List[Char]): List[Char] = s match {
case Nil => acc
case x :: xs => f(xs, x :: acc)
}
f(str, Nil).mkString
}