是否有一种内置的更优雅的方法来按元素类型过滤和映射集合?
如果我想缩小某个特定类型(例如 String
)的所有元素的 Iterable[A]
范围,我可以这样做:
as filter { _.isInstanceOf[String] }
但是,这显然是可取的 使用这个作为Iterable[String]
,可以通过map
来完成:
as filter { _.isInstanceOf[String] } map { _.asInstanceOf[String] }
这非常丑陋。当然,我可以使用 flatMap
代替:
as flatMap[String] { a =>
if (a.isInstanceOf[String])
Some(a.asInstanceOf[String])
else
None
}
但我不确定这是否更具可读性!我编写了一个函数,narrow
,它可以通过隐式
转换来使用:
as.narrow(classOf[String])
但我想知道是否有一个我忽略的更好的内置机制。特别是能够将 List[A]
缩小为 List[String]
,而不是 Iterable[String]
会很好。 code> 就像我的函数一样。
If I want to narrow, say, an Iterable[A]
for all elements of a particular type (e.g. String
) I can do:
as filter { _.isInstanceOf[String] }
However, it's obviously desirable to use this as an Iterable[String]
which can be done via a map
:
as filter { _.isInstanceOf[String] } map { _.asInstanceOf[String] }
Which is pretty ugly. Of course I could use flatMap
instead:
as flatMap[String] { a =>
if (a.isInstanceOf[String])
Some(a.asInstanceOf[String])
else
None
}
But I'm not sure that this is any more readable! I have written a function, narrow
, which can be used via implicit
conversions:
as.narrow(classOf[String])
But I was wondering if there was a better built-in mechanism which I have overlooked. Particularly as it would be nice to be able to narrow a List[A]
to a List[String]
, rather than to an Iterable[String]
as it will be with my function.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
isInstanceOf
/asInstanceOf
的 Scala 语法糖是模式匹配:因为它使用
flatMap
,所以它通常应该返回与开始时相同的集合。在 Scala 2.8 上,有一个实验函数可以执行这种模式,在对象 PartialFunction 中定义。所以,在 Scala 2.8 上你可以这样做:
看起来更大主要是因为我没有先导入该函数。但是,话又说回来,在 Scala 2.8 上有一种更直接的方法:
The Scala syntax sugar for
isInstanceOf
/asInstanceOf
is pattern matching:Because that uses
flatMap
, it should usually return the same collection you had to begin with.On Scala 2.8, there's an experimental function that does that kind of pattern, defined inside the object PartialFunction. So, on Scala 2.8 you can do:
Which looks bigger mostly because I did not import that function first. But, then again, on Scala 2.8 there's a more direct way to do it:
作为记录,这里是
narrow
的完整实现。与问题中给出的签名不同,它使用隐式Manifest
来避免某些字符:不幸的是,缩小到特定类型(例如
List[String]
)而不是Iterable[String]
有点难。它可以通过利用更高种类的 Scala 2.8.0 中的新集合 API 来完成,但在当前框架中不能。For the record, here's a full implementation of
narrow
. Unlike the signature given in the question, it uses an implicitManifest
to avoid some characters:Unfortunately, narrowing to a specific type (e.g.
List[String]
) rather thanIterable[String]
is a bit harder. It can be done with the new collections API in Scala 2.8.0 by exploiting higher-kinds, but not in the current framework.您将来可能会使用:
但现在不起作用。
欲了解更多信息,请访问以下链接:
http://lampsvn.epfl.ch/trac/scala/ticket/1089
http://lampsvn.epfl.ch/trac/scala/ticket/900
You may use in future:
But it doesn't work now.
For more information, go to the following links:
http://lampsvn.epfl.ch/trac/scala/ticket/1089
http://lampsvn.epfl.ch/trac/scala/ticket/900
保持形状:我现在有点匆忙,所以我把石膏留在那儿,但我很确定它可以被消除。这在主干中有效:
运行它:
Shape preserving: I'm a bit rushed right now so I'm leaving the cast in there, but I'm pretty sure it can be eliminated. This works in trunk:
Running it: