假设我的课程Point
有两个属性x
和y
以及k元组:
val p1 = (1,2)
val p2 = (3,4)
val p3 = (33,3)
val p4 = (6,67)
.
.
val p4 = (3,8)
我想编写一个我可以调用的函数:
val arrayOfPoints = tupleToArray(p1,p2,..,pk)
它会返回Array
Points
和
x
=元组的第一个值和y
=元组的第二个值。 注意:函数的参数个数可以是任何整数> = 1。
答案 0 :(得分:4)
Point
定义为案例类,我们可以使用(Int, Int)
将Point
元组转换为Point.tupled
。(Int, Int)*
接受可变数量的参数。将元组转换为Points
的函数可能如下所示:
case class Point(x: Int, y: Int)
def tupleToPoints(pairs: (Int, Int)*) =
pairs.map(Point.tupled).toArray
scala> tupleToPoints(p1, p2, p3, p4)
res2: Array[Point] = Array(Point(1,2), Point(3,4), Point(33,3), Point(6,67))
如果你有一组积分,你可以这样做:
val points = List(p1, p2, p3, p4)
tupleToPoints(points: _*)
关于Point.tupled
的一些额外说明:
当您致电Point(1, 1)
时,实际上是致电Point.apply(1, 1)
。如果我们检查Point.apply
的类型,我们可以看到它需要两个Ints
并返回Point
。
scala> Point.apply _
res21: (Int, Int) => Point = <function2>
在您的情况下,我们有一个元组(Int, Int)
,我们希望将其转换为Point
。第一个想法可能是模式匹配:
(1, 1) match { case (x, y) => Point(x, y) }
def tupleToPoints(pairs: (Int, Int)*) =
pairs.map { case (x, y) => Point(x, y) }.toArray
// nicer than map(p => Point(p._1, p._2))
但是,如果我们想直接使用元组来使用Point
创建Point.apply
,那么我们不需要这一步呢?我们可以使用tupled
:
scala> (Point.apply _).tupled
res22: ((Int, Int)) => Point = <function1>
我们现在有一个函数,它使用元组(Int, Int)
(而不是两个Ints
)并返回Point
。由于Point
是一个案例类,我们也可以使用Point.tupled
这是完全相同的函数:
scala> Point.tupled
res23: ((Int, Int)) => Point = <function1>
我们可以在地图中传递此功能:
def tupleToPoints(pairs: (Int, Int)*) =
pairs.map(Point.tupled).toArray
// analogous to map(p => Point.tupled(p))