0

I have a code like that:

var index = 0
var array: Array[String] = //initialized

functionOne(array(index))
index = index + 1
functionTwo(array(index))
index = index + 1

The idea is clear - I need to increment index each time when I get element from array. With java can simply write index++ intead of duplicating index = index+ 1 everywhere. Is there a pattern/api to refactor code above with scala?

Didier Dupont
  • 29,398
  • 7
  • 71
  • 90
Cherry
  • 31,309
  • 66
  • 224
  • 364

3 Answers3

3

If the use-case is to call a different function for each element of the array, then a neater solution is

var array: Array[String] = ??? // intialized
// as many functions as needed
val functions = Array(functionOne, functionTwo, functionThree);  

(array zip functions) foreach { case (el, f) => f(el) }

This is an example of a more general idea here that if you're not doing anything with the index value, just using it to access a collection, then probably there's a way of doing it that doesn't need the index at all.

The Archetypal Paul
  • 41,321
  • 20
  • 104
  • 134
0

You're thinking imperatively rather than functionally. If you wanted to apply a function to each element in an array within Scala, then the idiomatic way of doing it is to utilise the map function, so that you have something like:

val elements = Array(1,2,3,4,5)
val results = elements map { x => x+4}

If you need to utilise the index of each element in your function call, then transform the array into an array (or sequence) of pairs using zip with index like this:

scala> elements.zipWithIndex
res0: Array[(Int, Int)] = Array((1,0), (2,1), (3,2), (4,3), (5,4), (6,5))

Then you can apply a map again, this time applying a function which takes a pair rather than a single element:

scala> elements.zipWithIndex map { case (x,y) => (x, y*5) }
res2: Array[(Int, Int)] = Array((1,0), (2,5), (3,10), (4,15), (5,20), (6,25))

or

 scala> elements.zipWithIndex map { case (x, y) => x*y }
 res3: Array[Int] = Array(0, 2, 6, 12, 20, 30)

If you want to apply a different function per index, then just supply a different definition within the map closure:

scala> elements.zipWithIndex map { 
   case (0, y) => y + 45
 | case (1, y) => y + 5
 | case (_, y) => y
 | }
Jonny Coombes
  • 575
  • 2
  • 6
  • 1
    The quesrion about applying different function of array element. E.g. `functionOne` and `functionTwo` are different function calls. – Cherry Nov 06 '14 at 08:17
  • In that case you would just use a different function definition within the map closure...one which alters depending on the passed in index... – Jonny Coombes Nov 06 '14 at 08:20
  • The case-within-the-map is pretty ugly. If the OP wants to call one function on first, a different on the second, and so on then better is something like `(array.toList zip List( functionOne, functionTwo,[etc.])).foreach(case (el, f) => f(el))`? – The Archetypal Paul Nov 06 '14 at 08:59
  • Yep - good point Paul. That's cleaner and more readable really. – Jonny Coombes Nov 06 '14 at 09:08
0

Scala doesnot hav incremental operators. In place you can use index+=1. Please refer Why no i++ in scala?

Community
  • 1
  • 1
Sangeeth
  • 614
  • 1
  • 5
  • 14