Scala 可以在Iterable上进行模式匹配吗
在scalaScala 可以在Iterable上进行模式匹配吗,scala,pattern-matching,Scala,Pattern Matching,在scalaIterable[a]集合上有一种优雅的模式匹配方法,可以检查它是否为空,是否正好包含一个元素(并获取它),是否正好包含N个元素(并获取它们),是否至少包含一个或多个元素(并获取它或它们),等等 使用列表很简单,但我无法使用与Iterable相同的功能。这个怎么样: object Example extends App { val myIterable: Iterable[Int] = List(1,2).toIterable myIterable ma
Iterable[a]
集合上有一种优雅的模式匹配方法,可以检查它是否为空,是否正好包含一个元素(并获取它),是否正好包含N个元素(并获取它们),是否至少包含一个或多个元素(并获取它或它们),等等
使用列表
很简单,但我无法使用与Iterable
相同的功能。这个怎么样:
object Example extends App {
val myIterable: Iterable[Int] = List(1,2).toIterable
myIterable match {
case Nil =>
println(s" list is empty")
case a::Nil =>
println(s" list contains 1 elements $a")
case a::b::Nil =>
println(s" list contains 2 elements $a and $b")
}
}
是否要按以下方式进行模式匹配
val it: Iterable[Int] = ...
it match {
case Iterable(1, a, b) => ...
case Iterable(a, b) => ...
case Iterable() =>
}
如果是,实际上您不能这样做,因为Iterable的伴生对象没有unallyseq
方法。因此,最简单的方法是显式地将Iterable
转换为Seq
:
val it: Iterable[Int] = ...
it.toSeq match {
case Seq(1, a, b) => ...
case Seq(a, b) => ...
case Seq() =>
}
或者,如果您不想每次手动将Iterable
转换为Seq
,您可以使用以下方法:
object iterable {
def unapplySeq[A](it: Iterable[A]): Option[Seq[A]] = Some(it.toSeq)
}
val it: Iterable[Int] = ...
it match {
case iterable(1, a, b) => ...
case iterable(a, b) => ...
case iterable() =>
}
但请注意,基础集合可能不是Seq
。这种方法可能导致将整个Iterable
复制到新集合中
编辑:
Iterable
可能是无限的。在这种情况下,.toSeq
可能会使程序崩溃。
因此,最安全的方法是在模式匹配之前调用
。take(n)
看起来您总是在使用整个Iterable
。如果one element=>获取它
,如果iterable.size>=1获取它
,如果n elements=>获取它
,这意味着这些条件将始终为真。你唯一错过的是0元素。它们只是可能匹配的示例非常好的提示,谢谢。请注意,toSeq不会因无限多个Iterable集合而终止。我们可以先调用take(n),然后调用toSeq或直接调用list并使用列表模式匹配。我想直接在Iterable上实现它而不转换它,但这似乎是不可能的。无论如何,请修改您的答案,我们将以我们找到的最安全和最好的方式将其记录在案。这只适用于您的示例中,因为原始对象是一个列表。我认为它在一般情况下不起作用,请尝试使用数组快速检查它。