【问题标题】:Scala filter on two conditionsScala 在两个条件下过滤
【发布时间】:2012-06-23 01:32:17
【问题描述】:

我想同时根据两个条件过滤我的数据集。

有可能吗?

我想要这样的东西:

mystuff = mystuff.filter(_.isX && _.name == "xyz")

【问题讨论】:

    标签: arrays scala filter multiple-conditions


    【解决方案1】:

    使用稍微不那么简洁的 lambda 语法:

    mystuff = mystuff.filter(x => (x.isX && x.name == "xyz"))
    

    您可以找到有关 Scala 匿名函数语法here 的更多详细信息。

    【讨论】:

    • 这是否消除了性能开销?我的意思是最后查询是否正确表达?
    【解决方案2】:

    虽然根据“myStuff”是什么可能会对性能产生一些影响,但您始终可以过滤两次

    mystuff = mystuff.filter(_.isX).filter(_.name == "xyz")
    

    【讨论】:

    • 这会导致整个列表双循环。
    • @squixy 仅供参考,事实并非如此。 filter 创建集合的新投影(或视图),以便在迭代期间要求元素时(即mapfold 等...)filter 函数应用于查看元素是否返回
    • @ThaDon 不正确 - 它取决于集合类型,但最常见的(ArrayListVector...)会创建一个中间集合
    【解决方案3】:

    如果您需要频繁使用多个谓词进行过滤,您可以定义一种组合方式:

    case class And[A]( p1: A=>Boolean, p2: A=>Boolean ) extends (A=>Boolean) {
      def apply( a: A ) = p1(a) && p2(a)
    }
    

    这里是如何使用它来只保留大于 10 的奇数:

    scala> (0 until 20) filter And( _ > 10, _ % 2 == 1 )
    res3: scala.collection.immutable.IndexedSeq[Int] = Vector(11, 13, 15, 17, 19)
    

    以相同的方式编写 OrNot 组合子很容易。

    【讨论】:

    • 这种方法比使用 lambda 函数 mystuff.filter( each => each.isX && each.name.equals("xyz")) 有优势吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-13
    • 1970-01-01
    • 2018-01-09
    • 2020-07-07
    • 1970-01-01
    相关资源
    最近更新 更多