我是一个Scala新手,我只是在写一个简单的函数来反转一个给定的字符串:
def reverse(s: String) : String
for(i <- s.length - 1 to 0) yield s(i)
yield返回一个scala.collection.immutable.IndexedSeq[Char]类型的数据,不能直接转换为字符串(或者是其他类型?)
我该如何编写这个函数?
我是一个Scala新手,我只是在写一个简单的函数来反转一个给定的字符串:
def reverse(s: String) : String
for(i <- s.length - 1 to 0) yield s(i)
yield返回一个scala.collection.immutable.IndexedSeq[Char]类型的数据,不能直接转换为字符串(或者是其他类型?)
我该如何编写这个函数?
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)
这是一个简短的版本
def reverse(s: String) = ("" /: s)((a, x) => x + a)
编辑:或者更简单地说,我们有非常神秘的东西。
def reverse(s: String) = ("" /: s)(_.+:(_))
但我实际上不建议这样做...
foldLeft
(/:
只是该方法的简写名称),它接受一个初始值,然后从左到右对序列的每个值应用运算符。在这种情况下,序列是字符串,运算符只是将字符串的字符前置到结果中。 - Thomas Lockney"" /: s
是一种中缀符号的方法调用。由于方法 /:
以 :
结尾,因此调用是在 s
上进行的,并带有参数 ""
。如果您在 Scala 文档中查找 String,您将找不到它,因为它只是 Java 类,但您会发现 Strings 隐式转换为 StringOps
,并且在这里您将找到 /:
方法。它是柯里化的,并且需要第二个参数,这里是一个类型为 (String, Char) => String
的匿名函数。另请参见 https://dev59.com/VWs05IYBdhLWcg3wR_22,https://dev59.com/fHE95IYBdhLWcg3wft1w#2303291 - Luigi Plingedef reverse(s: String): String = {
if (s.isEmpty) ""
else reverse(s.tail) + s.head
}
根据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引入的重新设计的集合库的基础。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
scala> val sentence = "apple"
sentence: String = apple
scala> sentence.map(x => x.toString).reduce((x, y) => (y + x))
res9: String = elppa
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
}