将元组转换为点数组

时间:2015-07-28 17:27:17

标签: scala

假设我的课程Point有两个属性xy以及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。

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))