有什么干净的方法可以在 Scala 中结合 find 和 instanceof 吗?
我想在一些 Iterable 中找到一些符合某种给定类型的元素,并验证将该类型作为参数的谓词。
我用命令式编程的方式写了这个方法,看起来符合我的预期。有没有办法以更“scalaesque”的方式写这个?
def findMatch[T](it: Iterable[_], clazz: Class[T], pred: T => Boolean): Option[T] = {
val itr = it.iterator
var res: Option[T] = None
while (res.isEmpty && itr.hasNext) {
val e = itr.next()
if (clazz.isInstance(e) && pred(clazz.cast(e))) {
res = Some(clazz.cast(e))
}
}
res
}
I want to find in some Iterable some elements that both conform to some given type, and validates a predicate taking that type as an argument.
I wrote this method using imperative-style programming, which seems to conform to my expectations. Is there some way to write this in a more "scalaesque" way?
def findMatch[T](it: Iterable[_], clazz: Class[T], pred: T => Boolean): Option[T] = {
val itr = it.iterator
var res: Option[T] = None
while (res.isEmpty && itr.hasNext) {
val e = itr.next()
if (clazz.isInstance(e) && pred(clazz.cast(e))) {
res = Some(clazz.cast(e))
}
}
res
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果您想
查找
,然后映射
,您可以使用collect
。You can use
collect
if you want tofind
and thenmap
.您可以使用存在类型
X forSome{typeX}
而不是使用_
作为类型参数。然后,您可以使用提到的 find 方法编写它,并在 Option 类型上使用 map 方法:You can work with an existantial type
X forSome{typeX}
rather than using_
as type parameter. This then would enable you to write it with the mentioned find method and use the map method on the Option type:如果您将问题划分为子问题,则很容易找到更惯用的版本。
您希望
Iterable[Any]
中查找T
的所有实例,T
以使编译器很乐意For第一点,您可以轻松地在
Iterator
上使用filter
方法。因此,您将返回一个仅包含
T
的Iterator[Any]
。现在让我们说服编译器:好的,现在你有了一个 Iterator[T] ,所以你只需要找到满足你的谓词的第一个元素:
If you divide your problem into subproblems a more idiomatic version is easy to find.
You want to
T
in yourIterable[Any]
T
to make the compiler happyFor the first point you can easily use the
filter
Method onIterator
. So you havewhich returns you an
Iterator[Any]
that contains onlyT
s. Now let's convince the compiler:Okay, now you have an
Iterator[T]
- so you just need to find the first element fulfilling your predicate:您可以使用
Iterable
的find
方法和带有守卫的模式匹配:有关模式匹配的介绍,请查看:
http://programming-scala.labs.oreilly.com/ch03.html
You can use
Iterable
'sfind
method and pattern matching with a guard:For an introduction to pattern matching have a look at:
http://programming-scala.labs.oreilly.com/ch03.html