2013-12-10 4 views
2

У меня есть набор элементов, позволяет называть их Effect, и у меня есть список Cause, которые имеют набор possibleEffects : Set[Effect]Для понимания фильтрации вариантов из

мне нужно перебирать список эффектов и только вернуть сначала Cause Я нахожу для каждого Effect. Там могут быть перекрывающиеся причины, которые вызывают более одного из эффектов, поэтому результат должен быть в наборе. Мне нужно, чтобы это было как можно быстрее, потому что оно выполняется много раз. Я придумал следующее (не уверен, что это лучший способ, я новичок в scala).

Я пытаюсь использовать метод find(), который возвращает Option[Cause]. Есть ли способ отфильтровать те, которые возвращают None (это не произойдет на самом деле, всегда будет причина в списке, если у меня нет ошибки) и извлеките ее из монады Some в рамках понимания? Кажется, я не могу использовать matches.

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 
+0

Не было бы проще сделать установить пересечение? –

+0

Как я могу установить пересечение для достижения того, что мне нужно? Как только я нахожу одну «причину», которая влияет на «возможные эффекты», я хочу остановиться и перейти к следующему эффекту. Я не хочу итерации до конца. Если я что-то не понимаю. В действительности «возможные эффекты пересечения эффектов» всегда возвращают хотя бы один элемент, поэтому я говорю «Нет» никогда не произойдет – jbx

ответ

4

Потому что вы можете перебирать Option в наличии для понимания, вы можете изменить «=» на «< -» и это даст вам тот же результат, как сглаживаются

val firstCauses : Set[Cause] = (for { 
    effect <- effects 
    possibleCause <- allCauses.find(_.possibleEffects.contains(effect)) 
} yield possibleCause) 
+0

О, это звучит чисто! Что относительно случаев, когда есть Нет, будет ли он просто отфильтрован? – jbx

+2

Да, это будет отфильтровывать None и оставить значения Some –

+0

Мне нравится эта реализация, у вас нет промежуточной коллекции. Это уменьшает вычисление. – tiran

3

Вам не нужно фильтровать те, которые возвращают None. Вы можете превратить Set[Option[T]] в Set[T] с помощью метода flatten. Это позволит избавиться от None для вас:

> 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) 

Таким образом, чтобы быть ясным, вы можете yield в Option в вашем для понимания, и только flatten результат.