Note that there is already defined function:
scala> val x = "scala is awesome"
x: java.lang.String = scala is awesome
scala> x.reverse
res1: String = emosewa si alacs
But if you want to do that by yourself:
def reverse(s: String) : String =
(for(i <- s.length - 1 to 0 by -1) yield s(i)).mkString
or (sometimes it is better to use until, but probably not in that case)
def reverse(s: String) : String =
(for(i <- s.length until 0 by -1) yield s(i-1)).mkString
Also, note that if you use reversed counting (from bigger one to less one value) you should specify negative step or you will get an empty set:
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)
Answer from om-nom-nom on Stack OverflowNote that there is already defined function:
scala> val x = "scala is awesome"
x: java.lang.String = scala is awesome
scala> x.reverse
res1: String = emosewa si alacs
But if you want to do that by yourself:
def reverse(s: String) : String =
(for(i <- s.length - 1 to 0 by -1) yield s(i)).mkString
or (sometimes it is better to use until, but probably not in that case)
def reverse(s: String) : String =
(for(i <- s.length until 0 by -1) yield s(i-1)).mkString
Also, note that if you use reversed counting (from bigger one to less one value) you should specify negative step or you will get an empty set:
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)
Here's a short version
def reverse(s: String) = ("" /: s)((a, x) => x + a)
edit : or even shorter, we have the fantastically cryptic
def reverse(s: String) = ("" /: s)(_.+:(_))
but I wouldn't really recommend this...
s.head is never null. It'll throw an exception if the string is empty (or if it is null, which it should never be - nulls should never really appear in scala code).
Also, you are returning too early - x.tail.isEmpty means you still have one char remaining to process.
Finally, you always return "" instead of the actual result.
Something like this should work:
str match {
case "" => r
case s => rev(s.tail, s.head + r)
}
As mentioned in the comment, manipulating strings like this isn't very performant. So, in real life you'd probably want to convert it into a list, reverse the list, and then .mkstring to put it back together.
I Have created function which reverse the string using scala's tail recursion
def reverseString(str:String) = {
@tailrec
def reverseStringHelper(strTail:List[Char],reversedString :List[Char]):List[Char] = {
strTail match {
case Nil => reversedString
case head :: tail => {
reverseStringHelper(tail,head :: reversedString)
}
}
}
reverseStringHelper(str.toList,ListChar).mkString
}
If you found the answer helpful, please accept it.
Github Gist: https://gist.github.com/Deepak-nebhwani/0f0981027b61ff9f50904662614e7b7f
You can use the following definition:
def printNames(names: List[String]): String = {
if(names.isEmpty) ""
else printNames(names.tail) + " " + names.head
}
Note that this implementation is not tail recursive and cannot be optimized by scala compiler. I strongly advise using an accumulator for the resulting String.
Luis Miguel Mejía Suárez suggests using StringBuilder to avoid expensive String concatenation:
def printNames(names: List[String]): StringBuilder = {
if(names.isEmpty) new StringBuilder("")
else printNames(names.tail).append(" ").append(names.head)
}
def printNames(names: List[String]): String = names.reverse.mkString(" ")
You can reverse the name list and then use mkString with space as a separator. The above one can be used to achieve the same without recursion, as mkString by default uses StringBuilder.
As you were looking for a tail-recursive solution
import scala.annotation.tailrec
def printNames(names: List[String]): String = {
@tailrec
def printNamesHelper(
names: List[String],
acc: StringBuilder = new StringBuilder("")
): String = {
names match {
case Nil => acc.toString.trim
case head :: tail => printNamesHelper(tail, acc.append(head).append(" "))
}
}
printNamesHelper(names)
}
def printNamesReverse(names: List[String]): String = {
@tailrec
def printNamesReverseHelper(
names: List[String],
accum: List[String] = List.empty
): String = {
names match {
case Nil => printNames(accum)
case head :: tail => printNamesReverseHelper(tail, head :: accum)
}
}
printNamesReverseHelper(names)
}
printNames(List("Adam", "Framk"))
printNamesReverse(List("Adam", "Framk"))
Added scastie snippet below:
<script src="https://scastie.scala-lang.org/shankarshastri/0dxWt7K3S8CkkAffliLICQ/7.js"></script>