首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Scala:在一次操作中过滤和强制转换

Scala:在一次操作中过滤和强制转换
EN

Stack Overflow用户
提问于 2014-03-05 22:36:44
回答 2查看 645关注 0票数 2

在给定一个异构序列的情况下,我如何才能只提取特定类型的成员,并以一种类型安全的方式对这些成员进行操作?

如果我有:

代码语言:javascript
复制
trait Foo
case class Bar(baz: String)
case class Qux(bar: Bar, quux: String) extends Foo
case class Corge(grault: Int) extends Foo

如果我想用CorgesQuxes的混合序列.

代码语言:javascript
复制
val s = Seq[Foo](Corge(1), Qux(Bar("2"), "3"), Qux(Bar("4"), "5"), Corge(6), Qux(Bar("2"), "7"))

...and只提取按Bar分组的Quxes

代码语言:javascript
复制
Map(
  Bar(2) -> List(Qux(Bar(2),3), Qux(Bar(2),7)), 
  Bar(4) -> List(Qux(Bar(4),5))
)

我可以这么做:

代码语言:javascript
复制
s filter { f => f.isInstanceOf[Qux] } groupBy { 
    f => f.asInstanceOf[Qux].bar }

或者我可以这么做:

代码语言:javascript
复制
(s.filter({ f => f.isInstanceOf[Qux] }).asInstanceOf[Seq[Qux]]) groupBy { 
    q => q.bar }

但是,无论哪种方式,我都需要两次instanceOf检查,而我似乎应该能够用一次检查。或者一个都没有。我错过了什么聪明的模式匹配方案吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-03-05 22:55:45

比丹尼尔·马丁的解决方案更好的方法是使用collect

代码语言:javascript
复制
val a: Seq[Any] = List(1, 2, "asdf", 4)
a: Seq[Any] = List(1, 2, asdf, 4)

val b = a collect { case s: String => s }
b: Seq[String] = List(asdf)
票数 12
EN

Stack Overflow用户

发布于 2014-03-05 22:50:06

不需要显式的instanceOf,只需要在case中使用类的隐式类型。

代码语言:javascript
复制
$ scala
Welcome to Scala version 2.9.3 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_25).
Type in expressions to have them evaluated.
Type :help for more information.

scala> val a : Seq[Any] = List(1, 2, "asdf", 4)
a: Seq[Any] = List(1, 2, asdf, 4)

scala> val b = a flatMap {i:Any => i match { case s:String => Some(s); case _ => None }}
b: Seq[String] = List(asdf)

注意ab的类型。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22210905

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档