Вопрос

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
Это было полезно?

Решение

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)

Другие советы

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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top