加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

类 – Scala:基于类型进行过滤

发布时间:2020-12-16 09:11:32 所属栏目:安全 来源:网络整理
导读:我正在学习 Scala,因为它符合我的需要,但我发现很难很好地构建代码.我处于一种情况,我有一个List x,并且想要创建两个列表:一个包含SomeClass的所有元素,一个包含所有不是SomeClass的元素. val a = x collect {case y:SomeClass = y}val b = x filterNot {_.
我正在学习 Scala,因为它符合我的需要,但我发现很难很好地构建代码.我处于一种情况,我有一个List x,并且想要创建两个列表:一个包含SomeClass的所有元素,一个包含所有不是SomeClass的元素.

val a = x collect {case y:SomeClass => y}
val b = x filterNot {_.isInstanceOf[SomeClass]}

现在我的代码看起来像这样.然而,它不是非常有效,因为它迭代x两次,代码似乎有点黑客.有更好的(更优雅)的做事方式吗?

可以假定SomeClass没有子类.

解决方法

EDITED

虽然使用简单的分区是可能的,它会丢失在问题中收集的类型信息.

可以定义一个分区方法的变体,它接受使用以下两种方法返回两种类型之一的函数:

import collection.mutable.ListBuffer

def partition[X,A,B](xs: List[X])(f: X=>Either[A,B]): (List[A],List[B]) = {
  val as = new ListBuffer[A]
  val bs = new ListBuffer[B]
  for (x <- xs) {
    f(x) match {
      case Left(a) => as += a
      case Right(b) => bs += b
    }
  }
  (as.toList,bs.toList)
}

然后保留类型:

scala> partition(List(1,"two",3)) {
  case i: Int => Left(i)
  case x => Right(x)
}

res5: (List[Int],List[Any]) = (List(1,3),List(two))

当然,解决方案可以使用构建器和所有改进的收集功能进行改进:)??.

为了完整,我的旧答案使用平原分区:

val (a,b) = x partition { _.isInstanceOf[SomeClass] }

例如:

scala> val x = List(1,2,"three")
x: List[Any] = List(1,three)

scala> val (a,b) = x partition { _.isInstanceOf[Int] }
a: List[Any] = List(1,2)
b: List[Any] = List(three)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读