如何使用Scala 2.11.6 API将Array(e1,e2)转换为(e1,e2)?

时间:2015-05-10 12:30:57

标签: scala

假设:

scala> val ss = "hello_world".split("_")
ss: Array[String] = Array(hello, world)

如何将ss转换为功能为(hello, world)Array)的元组ss?我正在考虑一个函数,所以上面的代码段最终会以"hello_world".split("_").to[Tuple2]或类似的结果。

是否可以仅使用Scala 2.11.6 API?

3 个答案:

答案 0 :(得分:0)

我能提出的最短时间:

scala> "hello_world" split("_") match { case Array(f, s) => (f, s) }
res0: (String, String) = (hello,world)

当然,它会引发其他非Tuple2个案件。你可以这样做以避免除外:

scala> "hello_world" split("_") match { case Array(f, s) => Some(f, s); case _ => None } 
res1: Option[(String, String)] = Some((hello,world))

或暗示:

scala> implicit class ArrayTupple[T](val a: Array[T]) { def pair = a match { case Array(f, s) => (f, s) } }
defined class ArrayTupple

scala> val ss = "hello_world".split("_")
ss: Array[String] = Array(hello, world)

scala> ss.pair
res0: (String, String) = (hello,world)

我对解决方案仍然不满意。好像你必须要写出所有可能的案例,直到Tuple22来制作更通用的方法,如to[Tuple22]或者可能使用宏。

答案 1 :(得分:0)

不幸的是,没有任何功能可以将N个元素的Array(当然N <= 22)转换为TupleN。建议对Scala API [1]进行更改,以便将:++:方法添加到元组中,但它的优先级较低。人们在他们的项目中做的事情基本上是在SO问题中总结出来的[2]。

如果你按照他们的建议行事,并创建从TupleOps2到Tuple22`的类,那么它仍然是不可能的。请看下面的代码:

def array2Tuple[T](array: Array[T]): TupleN = {
  if(array.length == 2)
    (array(0), array(1))
  else
    array(0) +: array2Tuple(array.drop(1))
}

TupleN返回类型中推断N仍然是不可能的。这里的问题当然是数组的大小与元组的大小。数组的大小包含在对象内部,而Tuple的大小包含在类型名称中。

参考文献:

答案 2 :(得分:0)

我认为你不能比

做得更好
"size_known".split("_") match { case Array(a, b) => (a, b) }

Some("size_is_unknown".split("_")) collect { case Array(a, b) => (a, b) }

不重新发明Shapeless的某些功能,使其成为easy