Проверьте, содержит ли Seq [T] Option [T] - PullRequest
0 голосов
/ 05 апреля 2020

Предположим, у меня есть следующее

case class Foo(a: Option[Int])
val bar = Seq(Foo(Some(0)), Foo(Some(1)), Foo(None))
val baz = Seq(0, 2)

, и я хочу проверить, существует ли a типа Option[Int] в Seq[Int]

Это не работает

bar.map {
  case foo: Foo if !baz.contains(foo.a) => Foo(None)
  case foo: Foo => foo  
}

Поскольку a относится к типу Option[Int], поэтому contains(foo.a) всегда возвращает false

Я знаю, что могу сделать что-то вроде следующего:

bar.map {
  case foo: Foo if foo.a.isEmpty || !baz.contains(foo.a.get) => Foo(None)
  case foo: Foo => foo  
}
bar.map {
  case Foo(None) => Foo(None)
  case Foo(Some(a)) if !baz.contains(a) => Foo(None)
  case foo: Foo => foo
}

Но мне интересно, есть ли другой способ, в основном containsOption или любой другой интересный подход

Ответы [ 2 ]

6 голосов
/ 05 апреля 2020

Чтобы проверить, существует ли значение в Option, которое содержится в List, мы можем написать

Some(2).exists(baz.contains)           // true
Some(1).exists(baz.contains)           // false
Option.empty[Int].exists(baz.contains) // false

, таким образом, если вы пытаетесь отфильтровать bar по такому предикату, тогда

bar.filter(_.a.exists(baz.contains))
// List(Foo(Some(0)))

при попытке ответить на вопрос напрямую

bar.map(foo => if (foo.a.exists(baz.contains)) foo else Foo(None))
// List(Foo(Some(0)), Foo(None), Foo(None))
1 голос
/ 05 апреля 2020

Вы также можете использовать этот подход:

bar.collect {
  case Foo(Some(v)) => v
}.intersect(baz).nonEmpty

Соберите все элементы, которые присутствуют в Foo, затем выполните пересечение с коллекцией baz. Результат равен true, если в коллекции bar есть элементы, которые существуют в коллекции baz.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...