如何填充 ListBuffer[ List[Any] ] (Scala)?
How to fill a ListBuffer[ List[Any] ] (Scala)?
我有一个 ListBuffer 声明如下:
var distances_buffer: ListBuffer[List[Any]] = ListBuffer.empty[List[Any]]
我正在尝试用这样的数据填充它:
for(current <- 0 to training_list_length - 1){
//A and B are examples
distances_buffer(current) ++= List[Any](A,B)
}
但是我收到以下错误:
java.lang.IndexOutOfBoundsException: 0
我错过了什么?
编辑!更多信息:
我有一个点列表(名称:training_list)及其 class。 (x, y, class) :
training_list : List[((Double, Double, String))]
我还有一个额外的点,给出了 x 和 y 值。
我的目标是计算额外点与训练列表中每个点的欧氏距离,并创建如下所示的结果:
//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)...
如您所见,在列表中我想包括点的坐标(来自 training_list)、点的 class 以及距离。
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)
}
创建此列表后,我想根据距离对其进行排序。也卡在这里!
正如 Luis 所建议的那样,应尽可能避免使用 Any
和 var
,因此这里有一个示例可能会促使您考虑不同的方法
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)
输出
res0: List[(Point, Double)] = List((Point(4.3,3.0,Iris-setosa),3.4481879299133333), (Point(4.4,3.0,Iris-setosa),3.5440090293338704))
我从Xavier复制了距离计算。
从你命名事物的方式来看,你似乎来自 Python 背景。
我建议你先学习一下 Scala,因为我们非常不同。
不仅在样式方面 (如驼峰式与破折号式),而且在更基本的方面,如:
- 一个强大的静态类型系统。因此,像
Any
这样的东西通常是一种代码味道,在 99.99% 的情况下,完全没有必要。
- OOP 和 FP 的混合体。因此,您不必成为 FP 专家,但即使在 Scala 的 OOP 方面也有一些惯用的东西,例如 immutability和常见操作 (高阶函数),如
map
、flatMap
、filter
和 reduce
。
- 我们的 List 与 Python 非常不同,通过索引访问元素是
O(n)
(在 Python 中会是 O(1)
)。 Python 列表更像是一个可以调整大小的 Array。
- 此外,我们并没有真正的
for
循环。我们有一个叫做 for comprehension which is nothing more than syntactic sugar for calls to map
, flatMap
, filter
& in some cases foreach
. 的东西
这个清单可以继续列出,但我认为我的观点很明确。
Scala不仅是新语法,还是一种不同的编程方式。
无论如何,这是解决您问题的惯用方法。
(没必要,这是最好的方法,可以做很多变化)
// First lets create some custom types / classes to represent your data.
final case class Point(x: Double, y: Double)
final case class ClassifiedPoint(point: Point, clazz: String)
// Lets define the Euclidean distance function.
def euclideanDistance(p1: Point, p2: Point): Double =
math.sqrt(
math.pow((p1.x - p2.x), 2) +
math.pow((p1.y - p2.y), 2)
)
}
// This is what you need.
// Note that I made it somewhat more generic that is has to be.
// For example, instead of using the euclidean distance function directly on the body,
// we receive the distance function to use.
// Also, I use a technique called currying to split the arguments in different lists,
// This allows the caller to partially apply them.
def computeDistance(distanceFun: (Point, Point) => Double)
(trainingList: List[ClassifiedPoint])
(referencePoint: Point): List[(ClassifiedPoint, Double)] =
trainingList.map { classifiedPoint =>
val distance = distanceFun(classifiedPoint.point, referencePoint)
classifiedPoint -> distance
}
你可以这样使用。
val trainingList = List(
ClassifiedPoint(Point(x = 4.3d, y = 3.0d), clazz = "Iris-setosa"),
ClassifiedPoint(Point(x = 4.4d, y = 3.0d), clazz = "Iris-setosa")
)
// Partial application to create a new function.
val computeEuclideanDistance = computeDistance(euclideanDistance) _
computeEuclideanDistance(trainingList, Point(x = 3.0d, y = 0.0d))
// res: List[(ClassifiedPoint, Double)] =
// List(
// (ClassifiedPoint(Point(4.3, 3.0), "Iris-setosa"), 3.269556544854363),
// (ClassifiedPoint(Point(4.4, 3.0), "Iris-setosa"), 3.3105890714493698)
// )
我有一个 ListBuffer 声明如下:
var distances_buffer: ListBuffer[List[Any]] = ListBuffer.empty[List[Any]]
我正在尝试用这样的数据填充它:
for(current <- 0 to training_list_length - 1){
//A and B are examples
distances_buffer(current) ++= List[Any](A,B)
}
但是我收到以下错误:
java.lang.IndexOutOfBoundsException: 0
我错过了什么?
编辑!更多信息:
我有一个点列表(名称:training_list)及其 class。 (x, y, class) :
training_list : List[((Double, Double, String))]
我还有一个额外的点,给出了 x 和 y 值。
我的目标是计算额外点与训练列表中每个点的欧氏距离,并创建如下所示的结果:
//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)...
如您所见,在列表中我想包括点的坐标(来自 training_list)、点的 class 以及距离。
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)
}
创建此列表后,我想根据距离对其进行排序。也卡在这里!
正如 Luis 所建议的那样,应尽可能避免使用 Any
和 var
,因此这里有一个示例可能会促使您考虑不同的方法
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)
输出
res0: List[(Point, Double)] = List((Point(4.3,3.0,Iris-setosa),3.4481879299133333), (Point(4.4,3.0,Iris-setosa),3.5440090293338704))
我从Xavier复制了距离计算。
从你命名事物的方式来看,你似乎来自 Python 背景。
我建议你先学习一下 Scala,因为我们非常不同。
不仅在样式方面 (如驼峰式与破折号式),而且在更基本的方面,如:
- 一个强大的静态类型系统。因此,像
Any
这样的东西通常是一种代码味道,在 99.99% 的情况下,完全没有必要。 - OOP 和 FP 的混合体。因此,您不必成为 FP 专家,但即使在 Scala 的 OOP 方面也有一些惯用的东西,例如 immutability和常见操作 (高阶函数),如
map
、flatMap
、filter
和reduce
。 - 我们的 List 与 Python 非常不同,通过索引访问元素是
O(n)
(在 Python 中会是O(1)
)。 Python 列表更像是一个可以调整大小的 Array。 - 此外,我们并没有真正的
for
循环。我们有一个叫做 for comprehension which is nothing more than syntactic sugar for calls tomap
,flatMap
,filter
& in some casesforeach
. 的东西
这个清单可以继续列出,但我认为我的观点很明确。
Scala不仅是新语法,还是一种不同的编程方式。
无论如何,这是解决您问题的惯用方法。
(没必要,这是最好的方法,可以做很多变化)
// First lets create some custom types / classes to represent your data.
final case class Point(x: Double, y: Double)
final case class ClassifiedPoint(point: Point, clazz: String)
// Lets define the Euclidean distance function.
def euclideanDistance(p1: Point, p2: Point): Double =
math.sqrt(
math.pow((p1.x - p2.x), 2) +
math.pow((p1.y - p2.y), 2)
)
}
// This is what you need.
// Note that I made it somewhat more generic that is has to be.
// For example, instead of using the euclidean distance function directly on the body,
// we receive the distance function to use.
// Also, I use a technique called currying to split the arguments in different lists,
// This allows the caller to partially apply them.
def computeDistance(distanceFun: (Point, Point) => Double)
(trainingList: List[ClassifiedPoint])
(referencePoint: Point): List[(ClassifiedPoint, Double)] =
trainingList.map { classifiedPoint =>
val distance = distanceFun(classifiedPoint.point, referencePoint)
classifiedPoint -> distance
}
你可以这样使用。
val trainingList = List(
ClassifiedPoint(Point(x = 4.3d, y = 3.0d), clazz = "Iris-setosa"),
ClassifiedPoint(Point(x = 4.4d, y = 3.0d), clazz = "Iris-setosa")
)
// Partial application to create a new function.
val computeEuclideanDistance = computeDistance(euclideanDistance) _
computeEuclideanDistance(trainingList, Point(x = 3.0d, y = 0.0d))
// res: List[(ClassifiedPoint, Double)] =
// List(
// (ClassifiedPoint(Point(4.3, 3.0), "Iris-setosa"), 3.269556544854363),
// (ClassifiedPoint(Point(4.4, 3.0), "Iris-setosa"), 3.3105890714493698)
// )