Reputation: 22128
I have a set of items, lets call them Effect
, and I have a list of Cause
that have a set of possibleEffects : Set[Effect]
I need to iterate through the list of effects and only return the first Cause
I find for each Effect
. There might be overlapping causes that cause more than one of the effects, which is why the result needs to be in a set. I need this to be as fast as possible because it executes a lot of times. I have came up with the following (not sure if it is the best way, I am new to scala).
I am trying to use the find()
method which returns an Option[Cause]
. Is there a way to filter out the ones that return None
(it won't happen in reality, there will always be the cause in the list, unless I have a bug), and extract it from the Some monad within the for comprehension? I can't seem to be able to use matches
within it.
val firstCauses : Set[Cause] = (for {
effect <- effects
possibleCause = allCauses.find(_.possibleEffects.contains(effect))
//todo: filter out possibleCause if it is not Some(Cause), and get it out of the Some monad so that the yield takes it
} yield possibleCause).toSet
Upvotes: 3
Views: 663
Reputation: 843
Because you can iterate Option in a for-comprehension, you can change "=" to "<-" and this will give you the same result as flatten
val firstCauses : Set[Cause] = (for {
effect <- effects
possibleCause <- allCauses.find(_.possibleEffects.contains(effect))
} yield possibleCause)
Upvotes: 4
Reputation: 7466
You don't need to filter the ones that return None
. You can turn a Set[Option[T]]
into a Set[T]
with the flatten
method. This will get rid of the None
for you:
> val s = Set(Some(1), None, Some(2), None,Some(3) )
s: scala.collection.immutable.Set[Option[Int]] = Set(Some(1), None, Some(2), Some(3))
> s.flatten
res1: scala.collection.immutable.Set[Int] = Set(1, 2, 3)
So, to be clear, you can yield
the Option
in your for-comprehension and just flatten
the result.
Upvotes: 3