Reputation: 122
I am new to Scala and would appreciate any help regarding the following code:
var exp = (-3).to(2, 1)
var out = exp.map(i => java.lang.Float.floatToIntBits(math.pow(i, 2).toFloat))
Now, I want to write the following code:
for (i <- 0 until exp.length)
{if(exp(i) < 0)
{out(i) = out(i) >> exp(i).abs}
}
that is, I want to modify elements of the out
vector depending on the elements of the exp
vector by having a one-to-one mapping between the two vectors. I can't find a single online source which can help me do this. Please help.
Upvotes: 1
Views: 130
Reputation: 20415
The extra iteration can be avoided by adding the shifting to the lambda function either by exp(i)
if negative or by 0
(no effect) otherwise, like this,
var out = exp.map { i =>
val f = java.lang.Float.floatToIntBits(math.pow(i, 2).toFloat)
f >> (if (i < 0) -i else 0)
}
Note also
def step(i: Int) = if (i < 0) -i else 0
so that we can simplify the solution above as follows,
var out = exp.map { i =>
java.lang.Float.floatToIntBits(math.pow(i, 2).toFloat) >> step(i)
}
Upvotes: 0
Reputation: 6470
Or make the transformation explicit and arguably more readable by putting it in a function then just having a single map operation.
def fn(i: Int): Int = {
val o = java.lang.Float.floatToIntBits(math.pow(i, 2).toFloat)
if (i < 0) o >> i.abs
else o
}
exp.map(fn)
Upvotes: 0
Reputation: 850
The vector is immutable collection, you can't modify it, but you can create new one. For this, use for yield comprehension:
val res = for (i <- 0 until exp.length)
yield if(exp(i) < 0)
out(i) >> exp(i).abs
else
out(i)
or just convert your vector to an array:
val out = exp.map(i =>
java.lang.Float.floatToIntBits(math.pow(i, 2).toFloat)
).toArray
and modify your array.
Upvotes: 1
Reputation: 15074
The following should work:
out.zip(exp) map { case (o,e) => if (e < 0) o >> e.abs else o }
Upvotes: 1