I am building a list of different case class objects based on a loop and a pattern match. I want to exclude (skip) the items hitting the default case (essentially filtering the list, and mapping to types in one step).
I'm probably too new to Scala to see all the possibilities. My attempt:
val events = for (ev <- data ) yield {
ev.sport match {
case "FOOTBALL" => new FootballEvent(ev)
case "SOCCER" => new SoccerEvent(ev)
case _ => None
}
}
I could filter the list afterwards, but I suspect there's some fancy Scala way of doing this :)
Please let me know if you have any idea of how this should best be done!
It is not that it is yield syntax, but you can use collect with pattern matching:
val events = data.collect { ev => ev.sport match {
case "FOOTBALL" => new FootballEvent(ev)
case "SOCCER" => new SoccerEvent(ev)
}}
Unlike better known .map
and .foreach
it wont fail on "other" case and instead just drop unmatched items.
The standard filter in for-yield
is obtained with x <- y if f(x,..)
. Here is an example that uses a Partial Function.
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)
Note the similarity with Traversable.collect
1 mentioned in the other answer, which has this signature def
collect[B](pf: PartialFunction[A, B]): CC[B]
and returns "a new collection resulting from applying the given partial function pf to each element on which it is defined and collecting the results".
An alternative without if
is a variation of bwroga's deleted answer:
for { ev <- data;
x <- ev.sport match {
case "FOOTBALL" => Some(new FootballEvent(ev))
case "SOCCER" => Some(new SoccerEvent(ev))
case _ => None
}
} yield x
This filters by subsequently iterating through None (i.e. "0 items") or Some (i.e. "1 item") after the initial map.
1 If someone can tell me how to link to individual methods in the "new" scaladoc, I'd be most grateful.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With