【发布时间】:2013-05-08 19:18:55
【问题描述】:
在每个条目产生 0 或 1 个结果的集合上调用 map 的惯用方式是什么?
假设我有:
val data = Array("A", "x:y", "d:e")
我想要的结果是:
val target = Array(("x", "y"), ("d", "e"))
(删除没有冒号的任何内容,在冒号上拆分并返回元组)
所以理论上我想我想做这样的事情:
val attempt1 = data.map( arg => {
arg.split(":", 2) match {
case Array(l,r) => (l, r)
case _ => (None, None)
}
}).filter( _._1 != None )
我想做的是避免需要任何情况并摆脱filter。
我可以通过预过滤来做到这一点(但我必须测试两次正则表达式):
val attempt2 = data.filter( arg.contains(":") ).map( arg => {
val Array(l,r) = arg.split(":", 2)
(l,r)
})
最后,我可以使用 Some/None 和 flatMap...确实不需要 filter,但这是大多数 scala 程序员所期望的吗?
val attempt3 = data.flatMap( arg => {
arg.split(":", 2) match {
case Array(l,r) => Some((l,r))
case _ => None
}
})
在我看来,在 Scala 中会有一种惯用的方式来做到这一点,是吗?
【问题讨论】:
-
你会想要
.collect:) 虽然由于PartialFunction的设计,它仍然会为每个元素运行你的正则表达式两次:/ -
我收回“每个元素两次”的评论。看起来 Scala 现在在从匹配块构建其“神奇”部分函数时不会不必要地调用
unapply变得更加聪明。我仍然讨厌PartialFunction界面,但看起来他们现在跳过了一堆箍,尽可能减少它的愚蠢。
标签: scala