Velija Povlakic
Velija Povlakic

Reputation: 45

ObservableBuffer giving IndexOutOfBounds in Scala

I am mesmerized. The below code is giving me an indexoutofbound error. But if I were to delete the slashes enabling for(j <- i until tmpArray.length) it would work. I really do not understand why it is happening, and would appreciate an explanation.

 for(i <- 0 until tmpArray.length)
{
 // for(j <- i until tmpArray.length)
 // {
    if( date.getValue != null && tmpArray(i).date != date.getValue )
    {
      tmpArray.remove(i)
    }
//  }
}

Upvotes: 1

Views: 70

Answers (1)

Dylan
Dylan

Reputation: 13859

You're modifying the array as you "iterate" over it.

You are actually iterating over the range 0 until tmpArray.length, which is calculated up front. At some point, you reduce the length of the array (or, I assume so, as I can't find remove on the Array class). But it's still going to continue the iteration up to whatever the last index was when you created the range.

When you uncomment the inner for block, you're making it recompute the range for each step of the outer for. And it just so happens that the j range will simply have nothing in it if i >= tmpArray.length. So it inadvertently guards against that failure.

This is very C-style (imperative) code. It looks like all you're trying to do is remove some items from an array. That's what filter is for.

val result = tmpArray.filter { d =>
  if(date.getValue != null && d != date.getValue) false else true
}

This creates a new array (result) by passing an anonymous function to tmpArray.filter. It will pass each item in the array to your "predicate", and if it returns true, it'll keep that item in result, otherwise it will omit it.

You should note that I avoided saying "loop". Scala's for isn't for making loops. It's actually syntax sugar for calling methods like foreach and map. Google "scala for comprehensions" for more detail.

If you insist on creating a C-style loop using indexes and a loop variable, you'll want to use while, so that you can check if i < tmpArray.length each time.

Upvotes: 3

Related Questions