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?

1
  • 1
    You could use index += 1. Commented Nov 6, 2014 at 8:01

3 Answers 3

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.

Sign up to request clarification or add additional context in comments.

Comments

0

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

4 Comments

But there would be still two lines of code instead one line in Java.
@rtruszk, no there would be the same number of lines. In java, 2x index++. In Scala, 2x index+=1
@Paul No. In Java would be one line: functionOne(array[index++]) and in Scala two lines: functionOne(array(index)) and index+=1
Yes, you could write it in one line, but the OP didn't. So I don't see the two as equivalent. Anyway, messing with indexes at all isn't really needed. See my answer
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 | } 

4 Comments

The quesrion about applying different function of array element. E.g. functionOne and functionTwo are different function calls.
In that case you would just use a different function definition within the map closure...one which alters depending on the passed in index...
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))?
Yep - good point Paul. That's cleaner and more readable really.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.