Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check a condition within a foreach in scala

Tags:

foreach

scala

Is there a way to check a condition within a foreach loop in scala. The example is that I want to go through an array of integers and do some arbitrary math on the positive numbers.

val arr = Array(-1,2,3,0,-7,4) //The array

//What I want to do but doesn't work

arr.foreach{if(/*This condition is true*/)
              {/*Do some math and print the answer*/}}

//Expected answer for division by six is 0.333333333 \n 0.5 \n 0.666666667
//Which is 2/6, 3/6 and 4/6 respectively as they appear in the array

I know how to do it with a normal for loop and if statement but I want to use this because I want to get away from java.

Thanks

like image 726
Devan Avatar asked Jul 25 '17 08:07

Devan


2 Answers

foreach function brings every item in the list/array one by one, you should set it to a variable before to use it.

For example:

arr.foreach( variable_name => {
    if(/*This condition is true*/){
        /*Do some math and print the answer*/
    }
})
like image 161
ozata Avatar answered Oct 02 '22 14:10

ozata


The argument to foreach is a function, taking one argument, and returning a Unit. The argument is current element of the list, as it has been pointed out in other answers. You can just give it a name, and reference it as you would any other variable.

arr.foreach { x => if(x > 0) println(x/6.0) }

It is generally better and more idiomatic to split your logic into a chain of simpler "atomic" transformations rather than putting everything into one long function:

 arr
   .iterator
   .filter(_ > 0)
   .map(_ / 6.0)
   .foreach(println)

The underscore _ above is shorthand for the function argument. You can use it in short functions when you only need to reference the argument once, and a few other conditions are satisfied. The last line doesn't need to pass the argument to println, because println itself is a function, being passed to foreach. I could write it as .foreach(println(_)) or .foreach(x => println(x)), it would do the same thing, but is technically a little different: this form creates an anonymous function like def foo(x: Double) { println(x) } and passes it to foreach as an argument, the way I wrote it originally, just passes println itself as an argument.

Also, note a call to .iterator in the beginning. Everything would work the same way if you take it out. The difference is that iterators are lazy. The way it is written, the code will take first argument from the array, send it through filter, if it returns false, it'll stop, and go back to the second element, if filter returns true, it'll send that element to map, then print it out, then go back, grab the next element etc. Without .iterator call, it'd work differently: first, it would run the entire array through filter, and create a new array, containing only positive numbers, then, it'd run that new array through map, and create a new one, with the numbers divided by 6, then it'd go through this last array to print out the values. Using .iterator makes it more efficient by avoiding all the intermediate copies.

like image 36
Dima Avatar answered Oct 02 '22 12:10

Dima