Novalink Novalink - 2 months ago 8
Scala Question

Iterator values in Scala vs cached values with vals

I don't understand this behavior. I want to check if a value is in a circle created on a grid (as an array). Defining the two sides of the circle..

val circleLeft = Vector(5,14,23..)
val circleRight = Vector(5,16,27,..)


I'm checking with the below function this condition.
With the first one:

def insideCircle(idx: Int): Boolean = {
val l = circleLeft.toIterator
val r = circleRight.toIterator
while (l.hasNext && r.hasNext) {
if(idx < r.next && idx > l.next) return true
}
return false
}


It returns always true. With this second one

def insideCircle(idx: Int): Boolean = {
val l = circleLeft.toIterator
val r = circleRight.toIterator
while (l.hasNext && r.hasNext) {
val x1 = r.next
val x2 = l.next
println(x2,x1)
if(idx < x1 && idx > x2) return true
}
return false
}


It works properly, i.e. insideCircle(15) = true, insideCircle(17) = false

Is there something here different..?

Answer

&& is called short-circuit method (in Scala it's implemented with by-name argument). In your first example l.next is only executed if idx < r.next. In the second example l.next is executed always.

UPDATE

I would suggest more functional way:

def insideCircle(idx: Int): Boolean = {
  val l = circleLeft.toIterator
  val r = circleRight.toIterator
  r.zip(l).find {
    case (x1, x2) =>
      idx < x1 && idx > x2
  }
  .isDefined
}
Comments