Dexter
Dexter

Reputation: 1421

Print characters at even and odd indices from a String

Using scala, how to print string in even and odd indices of a given string? I am aware of the imperative approach using var. I am looking for an approach that uses immutability, avoids side-effects (of course, until need to print result) and concise.

Upvotes: 1

Views: 576

Answers (4)

Binzi Cao
Binzi Cao

Reputation: 1085

You can use the sliding function, which is quite simple:

scala> "abcdefgh".sliding(1,2).mkString("")
res16: String = aceg

scala> "abcdefgh".tail.sliding(1,2).mkString("")
res17: String = bdfh

Upvotes: 3

Mario Galic
Mario Galic

Reputation: 48420

Here is a tail-recursive solution returning even and odd chars (List[Char], List[Char]) in one go

def f(in: String): (List[Char], List[Char]) = {
  @tailrec def run(s: String, idx: Int, accEven: List[Char], accOdd: List[Char]): (List[Char], List[Char]) = {
    if (idx < 0) (accEven, accOdd)
    else if (idx % 2 == 0) run(s, idx - 1, s.charAt(idx) :: accEven, accOdd)
    else run(s, idx - 1, accEven, s.charAt(idx) :: accOdd)
  }
  run(in, in.length - 1, Nil, Nil)
}

which could be printed like so

val (even, odd) = f("abcdefg")
println(even.mkString)

Upvotes: 3

bottaio
bottaio

Reputation: 5093

val s = "abcd"
// ac
(0 until s.length by 2).map(i => s(i))
// bd
(1 until s.length by 2).map(i => s(i))

just pure functions with map operator

Upvotes: 2

mamdouh alramadan
mamdouh alramadan

Reputation: 8528

Another way to explore is using zipWithIndex

def printer(evenOdd: Int) {
    val str = "1234"
    str.zipWithIndex.foreach { i =>
      i._2 % 2 match {
        case x if x == evenOdd => print(i._1)
        case _ =>
      }
    }
  }

In this case you can check the results by using the printer function

scala> printer(1)
24
scala> printer(0)
13

.zipWithIndex takes a List and returns tuples of the elements coupled with their index. Knowing that a String is a list of Char

Looking at str

scala> val str = "1234"
str: String = 1234

str.zipWithIndex
res: scala.collection.immutable.IndexedSeq[(Char, Int)] = Vector((1,0), (2,1), (3,2), (4,3))

Lastly, as you only need to print, using foreach instead of map is more ideal as you aren't expecting values to be returned

Upvotes: 3

Related Questions