CervEd
CervEd

Reputation: 4253

Check if Seq[T] contains Option[T]

Suppose I have the following

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

and I want to check whether a of type Option[Int] exists in Seq[Int]

This doesn't work

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

Since a is of type Option[Int] so contains(foo.a) always returns false

I know I can do something like either of the following

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
}

But I wonder if there another way, basically a containsOption or any other interesting approach

Upvotes: 0

Views: 807

Answers (2)

Mario Galic
Mario Galic

Reputation: 48420

To check if there exists a value in an Option that is contained in a List we can write

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

thus if you are trying to filter bar on such predicate then

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

whilst trying to answer the question directly

bar.map(foo => if (foo.a.exists(baz.contains)) foo else Foo(None))
// List(Foo(Some(0)), Foo(None), Foo(None))

Upvotes: 6

Branislav Lazic
Branislav Lazic

Reputation: 14806

You can also use this approach:

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

Collect all elements which are present in Foo, then perform intersection with baz collection. The result is true if there are elements in bar collection that exist in baz collection.

Upvotes: 1

Related Questions