【问题标题】:How to slice a tuple in scala如何在scala中切片元组
【发布时间】:2012-06-19 09:32:51
【问题描述】:

我正在尝试对元组进行切片,删除最后两项。我尝试使用列表 drop/take 方法,但无法成功取回元组。

这是我尝试过的方法:

scala> val myTuple = (1, 2, 4, 5, 0, 5)
myTuple: (Int, Int, Int, Int, Int, Int) = (1,2,4,5,0,5)

scala> val myList = myTuple.productIterator.toList
myList: List[Any] = List(1, 2, 4, 5, 0, 5)

scala> val mySubList = myList.dropRight(2)
mySubList: List[Any] = List(1, 2, 4, 5)

scala> val mySubTuple = ???

我看到 here 元组列表在 scala 中(还没有?)是可能的。

是否有其他方法可以获取该子元组(无需处理 myTuple._1、myTuple._2...)?

【问题讨论】:

标签: scala


【解决方案1】:

这是shapeless 可以以通用 方式完成的事情,包括转换为HList

首先 - get shapeless。然后打开依赖方法类型运行 scala(在 2.10 中默认打开):

C:\Scala\sdk\scala-2.9.2\bin>scala -Ydependent-method-types
Welcome to Scala version 2.9.2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_04).
Type in expressions to have them evaluated.
Type :help for more information.

将 shapeless 添加到类路径中:

scala> :cp C:\Users\cmarsha\Downloads\shapeless_2.9.2-1.2.2.jar
Added 'C:\Users\cmarsha\Downloads\shapeless_2.9.2-1.2.2.jar'.  Your new classpath is:
"C:\tibco\tibrv\8.2\lib\tibrvnative.jar;C:\Users\cmarsha\Downloads\shapeless_2.9.2-1.2.2.jar"

现在让我们玩吧!

scala> (1, 2.3, 'a, 'b', "c", true)
res0: (Int, Double, Symbol, Char, java.lang.String, Boolean) = (1,2.3,'a,b,c,true)

我们必须导入无形

scala> import shapeless._; import Tuples._; import Nat._
import shapeless._
import Tuples._
import Nat._

我们把我们的元组变成HList

scala> res0.hlisted
res2: shapeless.::[Int,shapeless.::[Double,shapeless.::[Symbol,shapeless.::[Char,shapeless.::[java.lang.String,shapeless.::[Boolean,shapeless.HNil]]]]]] = 1 :: 2.3 :: 'a :: b :: c :: true :: HNil

然后我们取前4个(注意_4是类型参数,不是方法参数

scala> res2.take[_4]
res4: shapeless.::[Int,shapeless.::[Double,shapeless.::[Symbol,shapeless.::[Char, shapeless.HNil]]]] = 1 :: 2.3 :: 'a :: b :: HNil

现在转换回元组

scala> res4.tupled
res5: (Int, Double, Symbol, Char) = (1,2.3,'a,b)

我们可以缩短这个:

val (a, b, c, d) = sixtuple.hlisted.take[_4].tupled 
//a, b, c and d would all have the correct inferred type

这当然推广到N-tuple 的第一个M 元素

【讨论】:

  • 一定要包含-Ydependent-method-types,否则你会得到could not find implicit value for parameter tupler: shapeless.Tupler[take.Out](我困惑了一段时间,试图想出一个答案)
  • 很棒的答案,下午! (法国时区:))
  • 在 shapeless 2.00 中发生了什么变化?无法编译
【解决方案2】:
scala> val myTuple = (1, 2, 4, 5, 0, 5)
myTuple: (Int, Int, Int, Int, Int, Int) = (1,2,4,5,0,5)

scala> myTuple match {
     |   case (a, b, c, d, _, _) => (a, b, c, d)
     | }
res0: (Int, Int, Int, Int) = (1,2,4,5)

【讨论】:

  • 它可以工作,但需要显式编写模式匹配。无论元组的长度如何,我都在寻找一种方法。
  • 查看我的答案 - 我有一个使用 Miles Sabin 的无形库的完整通用示例
【解决方案3】:

怎么样:

scala> val myTuple = (1,2,4,5,0,5) myTuple: (Int, Int, Int, Int, Int, Int) = (1,2,4,5,0,5) scala> val (left,right):Tuple2[List[Int],List[Int]] = myTuple.productIterator.toList.splitAt(myTuple.productArity - 2) 左:List[Int] = List(1, 2, 4, 5) 右:List[Int] = List(0, 5) scala> val mytuple2 = (right(0),right(1)) mytuple2: (Int, Int) = (0,5)

【讨论】:

  • 太棒了 :) 我不知道元组是 Product-s 并且有可用的迭代器和 arity
猜你喜欢
  • 1970-01-01
  • 2016-02-23
  • 2015-11-28
  • 1970-01-01
  • 2014-02-03
  • 2018-11-21
  • 1970-01-01
  • 1970-01-01
  • 2016-04-16
相关资源
最近更新 更多