It there an elegant way to pattern match on a scala Iterable[A]
collection, to check if it's empty, if it contains exactly one element (and get it), if it contains exactly N elements (and get them), if it contains at least one or more elements (and get it or them), and so on.
With List
it's trivial, but I'm not able to have the equivalent for Iterable
working.
Do you want to do pattern matching in the following way?
val it: Iterable[Int] = ...
it match {
case Iterable(1, a, b) => ...
case Iterable(a, b) => ...
case Iterable() =>
}
If yes, actually you can't do it because Iterable's companion object doesn't have unapplySeq
method. So the easiest way to do so is explicitly converting Iterable
to Seq
:
val it: Iterable[Int] = ...
it.toSeq match {
case Seq(1, a, b) => ...
case Seq(a, b) => ...
case Seq() =>
}
Or if you don't want to convert Iterable
to Seq
every time by hand, you can use something like this:
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() =>
}
But be aware that underlying collection may not be a Seq
. This approach may lead to copying the whole Iterable
into a new collection.
EDIT:
Iterable
may be infinite. In this case .toSeq
may crash your program.
So the safest way will be calling .take(n)
before pattern matching
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With