基于Collection的多任务

时间:2012-01-28 13:01:57

标签: scala collections tuples

修改

最初的问题是“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是什么?

5 个答案:

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

Seqs to tuple

要从Seq执行多项任务,请执行以下操作?

val Seq(clazz, date) = captures

如您所见,无需限制为List;如果长度不匹配,此代码将抛出MatchError(在您的情况下,这很好,因为这意味着您犯了一个错误)。然后,您可以添加

(clazz, date)

重新创建元组。

来自比赛的元组

然而,Jed Wesley-Smith发布了一个解决方案,可以避免这个问题并更好地解决原始问题。特别是,在您的解决方案中,您有一个未指定长度的Seq,因此如果您犯了错误,编译器将不会告诉您;使用元组代替编译器可以帮助你(即使它无法检查正则表达式)。