Search code examples
scalalistappendindexoutofboundsexceptionlistbuffer

How to fill a ListBuffer[ List[Any] ] (Scala)?


I have a ListBuffer declared like this:

var distances_buffer: ListBuffer[List[Any]] = ListBuffer.empty[List[Any]]

and I am trying to fill it with data like this:

for(current <- 0 to training_list_length - 1){
   //A and B are examples
   distances_buffer(current) ++= List[Any](A,B)
}

However I get the following error:

java.lang.IndexOutOfBoundsException: 0

What am I missing?

EDIT! More Info:

I have a list (Named: training_list) of points and their class. (x, y, class) :

training_list : List[((Double, Double, String))]

I also have an extra point with a x and a y value given.

My goal is to calculate the euclidean distance of the extra point from each point inside the training list, and create a result which look like this:

//example
List((x: Double, y: Double, class: String), distance: String)

List((4.3,3.0,Iris-setosa), 1.2529964086141665), (4.4,3.0,Iris-setosa), 1.341640786499874)...

As you can see, in the list I want to include the coordinates of the point (from the training_list), the class of the point and also the distance.

for(current <- 0 to training_list_length - 1){
    val dist = eDistance(test_x, test_y, training_x(current), training_y(current))
    distances_buffer += ListBuffer[Any](training_result(current),dist)
  }

After the creation of this list I want to sort it based on the distances. Also stuck here!


Solution

  • As suggested by Luis, Any and var are to be avoided if possible, so here is an example that might nudge you to consider a different approach

    case class Point(x: Double, y: Double, `class`: String)
    
    def distance(a: Point, b: Point): Double =
      math.hypot(a.x - b.x, a.y - b.y)
    
    val targetPoint = Point(1,2,"Extra-point")
    val training_list : List[((Double, Double, String))] = List((4.3,3.0,"Iris-setosa"), (4.4,3.0,"Iris-setosa"))
    val points = training_list.map(Point.tupled)
    val unsortedPoints: List[(Point, Double)] = points.map(point => (point, distance(point, targetPoint)))
    unsortedPoints.sortBy(_._2)
    

    which outputs

    res0: List[(Point, Double)] = List((Point(4.3,3.0,Iris-setosa),3.4481879299133333), (Point(4.4,3.0,Iris-setosa),3.5440090293338704))
    

    I have copied distance calculation from Xavier.