修改
最初的问题是“Collection to Tuple”,因为我认为我需要一个元组来进行变量多任务。事实证明,人们可以直接对集合进行变量多重赋值。相应地重新提出了问题。
原始 有一个从我想要转换为元组的正则表达式派生的简单Seq [String]。
最直接的方法是什么?
我目前有:
val(clazz, date) = captures match {
case x: Seq[String] => (x(0), x(1))
}
哪个好,但我的路由层有一堆正则表达式匹配的路由,我将在val(a,b,c)上进行多项分配(捕获组始终是已知的,因为路由未处理,如果正则表达式不匹配)。如果有一个更精简的解决方案比匹配{case .. => ..}
在Scala中将集合转换为元组的最短1-liner是什么?
答案 0 :(得分:5)
这不是问题的答案,但可能以不同的方式解决问题。
你知道你可以匹配xs: List[String]
,如此:
val a :: b :: c :: _ = xs
这会将列表的前三个元素分配给a,b,c
吗?您可以在Seq
的声明中匹配其他内容,例如val
,就像在case
语句中一样。请务必注意匹配错误:
Catching MatchError at val initialisation with pattern matching in Scala?
答案 1 :(得分:3)
您可以使用Scalaz中的|>
运算符使其更好一些。
scala> val captures = Vector("Hello", "World")
captures: scala.collection.immutable.Vector[java.lang.String] = Vector(Hello, World)
scala> val (a, b) = captures |> { x => (x(0), x(1)) }
a: java.lang.String = Hello
b: java.lang.String = World
如果您不想使用Scalaz,可以自己定义|>
,如下所示:
scala> class AW[A](a: A) {
| def |>[B](f: A => B): B = f(a)
| }
defined class AW
scala> implicit def aW[A](a: A): AW[A] = new AW(a)
aW: [A](a: A)AW[A]
修改强>
或者像@ ziggystar的建议:
scala> val Vector(a, b) = captures
a: java.lang.String = Hello
b: java.lang.String = World
您可以使其更简洁,如下所示:
scala> val S = Seq
S: scala.collection.Seq.type = scala.collection.Seq$@157e63a
scala> val S(a, b) = captures
a: java.lang.String = Hello
b: java.lang.String = World
答案 2 :(得分:2)
正如@ziggystar在评论中所提出的,你可以做类似的事情:
val (clazz, date) = { val a::b::_ = capture; (a, b)}
或
val (clazz, date) = (capture(0), capture(1))
如果在确定之前验证了列表的类型,但要注意Seq
的长度,因为即使列表的大小为0或1,代码也会运行。
答案 3 :(得分:2)
您的问题最初专门用于在正则表达式中分配各个捕获组,这已经允许您直接从它们分配:
scala> val regex = """(\d*)-(\d*)-(\d*)""".r
regex: scala.util.matching.Regex = (\d*)-(\d*)-(\d*)
scala> val regex(a, b, c) = "29-1-2012"
d: String = 29
m: String = 1
y: String = 2012
显然你也可以在案例中使用这些:
scala> "29-1-2012" match { case regex(d, m, y) => (y, m, d) }
res16: (String, String, String) = (2012,1,29)
然后根据需要对这些进行分组。
答案 4 :(得分:0)
要从Seq
执行多项任务,请执行以下操作?
val Seq(clazz, date) = captures
如您所见,无需限制为List
;如果长度不匹配,此代码将抛出MatchError
(在您的情况下,这很好,因为这意味着您犯了一个错误)。然后,您可以添加
(clazz, date)
重新创建元组。
然而,Jed Wesley-Smith发布了一个解决方案,可以避免这个问题并更好地解决原始问题。特别是,在您的解决方案中,您有一个未指定长度的Seq,因此如果您犯了错误,编译器将不会告诉您;使用元组代替编译器可以帮助你(即使它无法检查正则表达式)。