scala 仅当模式匹配时才产生
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15122322/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Yield only if pattern match
提问by Joernsn
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:
我可能对 Scala 太陌生,无法看到所有的可能性。我的尝试:
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 :)
之后我可以过滤列表,但我怀疑有一些奇特的 Scala 方法可以做到这一点:)
Please let me know if you have any idea of how this should best be done!
如果您对如何最好地完成此操作有任何想法,请告诉我!
回答by om-nom-nom
It is not that it is yield syntax, but you can use collect with pattern matching:
并不是它是 yield 语法,而是您可以将 collect 与模式匹配一起使用:
val events = data.collect { ev => ev.sport match {
case "FOOTBALL" => new FootballEvent(ev)
case "SOCCER" => new SoccerEvent(ev)
}}
Unlike better known .mapand .foreachit wont fail on "other" case and instead just drop unmatched items.
与众所周知的不同.map,.foreach它不会在“其他”情况下失败,而只会丢弃不匹配的项目。
回答by Joernsn
The standard filter in for-yieldis obtained with x <- y if f(x,..). Here is an example that uses a Partial Function.
标准过滤器 infor-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)
Note the similarity with Traversable.collect1mentioned 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".
请注意与另一个答案中提到的1的相似性,它具有此签名并返回“通过将给定的部分函数 pf 应用于定义它的每个元素并收集结果而产生的新集合”。Traversable.collectdef
collect[B](pf: PartialFunction[A, B]): CC[B]
An alternative without ifis a variation of bwroga's deleted answer:
另一种选择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
This filters by subsequently iterating through None (i.e. "0 items") or Some (i.e. "1 item") after the initial map.
这通过随后在初始映射之后迭代 None(即“0 项”)或 Some(即“1 项”)来进行过滤。
1If someone can tell me how to link to individual methods in the "new" scaladoc, I'd be most grateful.
1如果有人能告诉我如何链接到“新”scaladoc 中的各个方法,我将不胜感激。

