Возможно ли сопоставление с образцом на Iterable - PullRequest
0 голосов
/ 11 октября 2018

Это элегантный способ сопоставления с образцом в коллекции scala Iterable[A], чтобы проверить, является ли он пустым, содержит ли он ровно один элемент (и получить его), содержит ли он ровно N элементов (и получить их), еслион содержит как минимум один или несколько элементов (и получит его или их) и т. д.

С List это тривиально, но я не могу получить эквивалент для Iterable работы.

Ответы [ 2 ]

0 голосов
/ 11 октября 2018

Вы хотите выполнить сопоставление с шаблоном следующим образом?

val it: Iterable[Int] = ...
it match {
  case Iterable(1, a, b) => ...
  case Iterable(a, b) => ...
  case Iterable() =>
}

Если да, на самом деле вы не можете сделать это, потому что объект-компаньон Iterable не имеет unapplySeq метода.Так что самый простой способ сделать это - явное преобразование 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 в новую коллекцию.

EDIT:

Iterable может быть бесконечным.В этом случае .toSeq может привести к сбою вашей программы.Поэтому самым безопасным способом будет вызов .take(n) до сопоставления с шаблоном

0 голосов
/ 11 октября 2018

Как насчет этого:

   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")
    }
  }
...