1

I have two arrays, upper and lower bound.

val solution : Array[Double] = Array(1.0, 33.0, 31.0, 82.0, 51.0, 25.0, 39.0, 96.0, 95.0, 49.0)
val original : Array[Double] = Array(3.0, 45.0, 18.0, 25.0, 99.0, 6.0, 36.0, 61.0, 82.0, 62.0)
val lower = 30
val upper = 90

Array of type Boolean is created using solution array.

val idx_lowest : Array[Boolean]  = solution.map ( x => x < lower )
idx_lowest: Array[Boolean] = Array(true, false, false, false, false, true, false, false, false, false)

Find indexes in idx_lowest where value is true

val trueIndexes = idx_lowest .zipWithIndex filter(x => x._1  ) map(_._2)
trueIndexes: Array[Int] = Array(0, 5)

Find values against trueIndexes in original array.

val tmp = trueIndexes map original
Array[Double] = Array(3.0, 6.0)

Perform operation on elements of tmp array.

val tmp1 = tmp  map (x => (x+lower)/2.0)
Array[Double] = Array(16.5, 18.0)

Update elements of solution array. Indexes are specified by trueIndexes. Elements those are less than lower bound are updated.

for(i <- tmp1.indices)  {
    solution(trueIndexes(i)) = tmp1(i)
  }

The updated solution array is:

Array[Double] = Array(16.5, 33.0, 31.0, 82.0, 51.0, 18.0, 39.0, 96.0, 95.0, 49.0)

Same steps have to be performed to update elements that are greater than upper bound. Here is code.

val idx_false : Array[Boolean]  = solution.map ( x => x > upper )
val falseIndexes = idx_false .zipWithIndex filter(x => x._1  ) map(_._2)
val tmp2 = falseIndexes map original 
val tmp3 = tmp2 map (x => (x+upper)/2.0)
for(i <- tmp3.indices)  {
   solution(falseIndexes(i)) = tmp3(i)
}
solution

This code doing exactly what I needed but have to perform lot of operations. In iterative algorithm I have to perform these operation in each iteration for each array. Is there more efficient,optimal and faster way to perform same operation?

2 Answers 2

4

You can zip them and map in a single operation:

solution.zip(original)
  .map { case(s, o) => if(s < lower) ((o + lower) / 2, o) else (s, o) }
  .map { case(s, o) => if(s > upper) (o + upper) / 2 else s }
Sign up to request clarification or add additional context in comments.

Comments

3

Isn't this the same result?

val done = solution.indices.map{x =>
  if (solution(x) < lower)      (lower + original(x))/2.0
  else if (solution(x) > upper) (upper + original(x))/2.0
  else solution(x)
}.toArray

1 Comment

I might be nitpicky, but it's not equivalent. From the business perspective this might be wrong, but if you set lower > upper, the the result is different. But if it's not the case, then the solution is quite elegant

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.