2013-02-27 10 views
12

Buduję listę różnych obiektów klasy sprawy na podstawie pętli i dopasowania wzorca. Chcę wykluczyć (pominąć) elementy trafiające w domyślny przypadek (zasadniczo filtrując listę i odwzorowując typy w jednym kroku).Wydajność tylko w przypadku dopasowania wzorca

Jestem prawdopodobnie zbyt nowy dla Scali, aby zobaczyć wszystkie możliwości. Moja próba:

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

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

    } 

mogę filtrować listę później, ale podejrzewam, że istnieje jakiś fantazyjny Scala sposób to zrobić :)

Proszę dać mi znać, jeśli masz jakiś pomysł, jak to powinno być najlepiej zrobić !

+0

Jeśli występują tylko dwa przypadki, zamiast trzech lub więcej, można to zrobić w jednym 'dla ... yield' - oto przykład:' dla {Some (x) <- Some (None: Option [String])} yield "should not get here" ' –

Odpowiedz

27

To nie jest to, że wydajność składni, ale można użyć zbierać z dopasowywania wzoru:

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

przeciwieństwie lepiej znany .map i .foreach to przyzwyczajenie nie na „inne” sprawy i zamiast po prostu upuścić niedopasowane elementy.

+1

Zostawię cię, ponieważ odpowiedziałeś jako pierwszy, ale żadne z nas nie miało tego za pierwszym podejściem. Okay, wygląda na to, że naprawiłeś błąd składni :) –

+0

nie zauważyłeś zbieram b4. – javadba

9

Standardowy filtr w for-yield jest uzyskiwany z x <- y if f(x,..). Oto przykład, który używa Częściowej funkcji.

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) 

Uwaga podobieństwo z Traversable.collect wymienionego w drugiej odpowiedzi, która ma ten podpis def collect[B](pf: PartialFunction[A, B]): CC[B] i powroty „nową kolekcję wynikającej z zastosowania danej częściowej funkcji pf do każdego elementu, na którym jest zdefiniowany i zbieranie wyniki".

Alternatywą bez if jest odmianą bwroga usuwana odpowiedź:

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

filtruje by następnie iteracja Brak (Ie „0 przedmiotów”) lub niektóre z nich (czyli „1 element”) po początkowym mapie .


Jeśli ktoś może mi powiedzieć jak to odwołuje się do poszczególnych metod w „nowej” scaladoc, byłbym bardzo wdzięczny.

+1

Dzięki! Skończyłem próbując wszystkich podejść – Joernsn

+0

Link do aktualnych skaladocs dla 'scala.collection.Traversable' http://www.scala-lang.org/api/current/scala/collection/Traversable.html – Davos

Powiązane problemy