Scala:基于类型过滤 [英] Scala: Filtering based on type

查看:258
本文介绍了Scala:基于类型过滤的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习Scala,因为它适合我的需要,但我发现很难结构代码优雅。我在一个列表 x 并且想要创建两个列表 s:一个包含 SomeClass 的所有元素,一个包含所有不是 SomeClass

I'm learning Scala as it fits my needs well but I am finding it hard to structure code elegantly. I'm in a situation where I have a List x and want to create two Lists: one containing all the elements of SomeClass and one containing all the elements that aren't of SomeClass.

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

我的代码看起来像。然而,它不是很有效,因为它重复 x 两次,代码看起来有点怪。是否有更好的(更优雅的)处理方式?

Right now my code looks like that. However, it's not very efficient as it iterates x twice and the code somehow seems a bit hackish. Is there a better (more elegant) way of doing things?

可以假设 SomeClass 没有子类。

推荐答案

已编辑

使用简单分区是可能的,它丢失了 collect 在问题中保留的类型信息。

While using plain partition is possible, it loses the type information retained by collect in the question.

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

One could define a variant of the partition method that accepts a function returning a value of one of two types using Either:

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))

当然,使用构建器和所有改进的集合东西可以改进解决方案:)。

Of course the solution could be improved using builders and all the improved collection stuff :) .

为了完整性,我的旧答案使用简单的分区

For completeness my old answer using plain partition:

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

例如:

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

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

这篇关于Scala:基于类型过滤的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆