Подтвердить что ты не робот

Выход возможен только в случае совпадения рисунка

Я создаю список различных объектов класса case на основе цикла и соответствия шаблона. Я хочу исключить (пропустить) элементы, ударяющие случай по умолчанию (по существу, фильтрацию списка и сопоставление типов в один шаг).

Я, вероятно, слишком новичок в Scala, чтобы увидеть все возможности. Моя попытка:

    val events = for (ev <- data ) yield {

        ev.sport match {
            case "FOOTBALL" => new FootballEvent(ev)
            case "SOCCER" => new SoccerEvent(ev)
            case _ => None
        }

    }

Затем я мог бы фильтровать список, но я подозреваю, что есть способ Scala сделать это:)

Пожалуйста, дайте мне знать, если у вас есть представление о том, как это лучше всего сделать!

4b9b3361

Ответ 1

Это не то, что это синтаксис yield, но вы можете использовать collect с сопоставлением с образцом:

val events = data.collect { ev => ev.sport match {
     case "FOOTBALL" => new FootballEvent(ev) 
     case "SOCCER"   => new SoccerEvent(ev)
}}

В отличие от более известных .map и .foreach, он не будет терпеть неудачу в "другом" случае и вместо этого просто удаляет непревзойденные элементы.

Ответ 2

Стандартный фильтр в for-yield получается с помощью x <- y if f(x,..). Вот пример, который использует частичную функцию.

val m: PartialFunction[Event, Event] = ev => ev.sport match {
  case "FOOTBALL" => new FootballEvent(ev)
  case "SOCCER" => new SoccerEvent(ev)
};

for { ev <- data if m.isDefindAt(ev)  
      val x = m(ev)
} yield x

// or, without the temporary binding:
for (ev <- data if m.isDefindAt(ev)) yield m(ev)

Обратите внимание на сходство с Traversable.collect 1 упомянутым в другом ответе, который имеет эту подпись def collect[B](pf: PartialFunction[A, B]): CC[B] и возвращает "новый сбор, полученный в результате применения данной частичной функции pf к каждому элементу, на котором он определен, и собиранию результатов".

Альтернатива без if - это вариация ответа bwroga:

for { ev <- data;
      x <- ev.sport match {
        case "FOOTBALL" => Some(new FootballEvent(ev))
        case "SOCCER" => Some(new SoccerEvent(ev))
        case _ => None
      }
} yield x

Это фильтрует путем последующего итерации через None (т.е. "0 элементов" ) или некоторых (то есть "1 элемент" ) после начальной карты.


1 Если кто-то может сказать мне, как связать себя с отдельными методами в "новом" scaladoc, я был бы очень благодарен.