【问题标题】:Filtering on Scala Option[Set]过滤 Scala 选项[Set]
【发布时间】:2012-05-26 00:44:51
【问题描述】:

我有一个 Option[Set[String]] 类型的 Scala 值,我试图在集合 filter 方法中使用它:

val opt: Option[Set[String]] = ...

collection.filter {
  value =>
  opt match {
    case Some(set) => set.contains(value)
    case None => true
  }
}

如果opt 的值为Some(...) 我想使用封闭的Set 来过滤集合,否则我想包含集合中的所有项目。

有没有更好(更惯用)的方式来使用OptionmapfiltergetOrElse 等)?

opt 来自一个可选的命令行参数,其中包含要包含的术语列表。如果缺少命令行参数,则包括所有术语。

【问题讨论】:

    标签: scala filtering option


    【解决方案1】:

    我会使用 Set[A] 扩展 A => Boolean 并将返回 true 的常量函数传递给 getOrElse 的事实:

    val p: String => Boolean = opt.getOrElse(_ => true)
    

    或者:

    val p = opt.getOrElse(Function.const(true) _)
    

    现在你可以写collection.filter(p)。如果您想要单线,以下任一方法也可以:

    collection filter opt.getOrElse(_ => true)
    collection filter opt.getOrElse(Function.const(true) _)
    

    【讨论】:

    • Function.const(...) BTW 的目的是什么?
    • 如果集合包含自定义类而不是String,有没有办法使用您的方法检查其中一个实例字段(例如name)?如果在集合上执行map 以将其转换为String,我会丢失类内容,稍后在方法链中需要这些内容。顺便说一句,您的方法对我的 String 集合非常有效。谢谢。
    • @Ralph:如果你已经定义了p,你可以使用collection.filter(x => p(x.name))
    【解决方案2】:

    过滤_ => true似乎有点浪费,所以我更喜欢

    opt match {
      case Some(s) => collection filter s
      case None    => collection
    }
    

    我猜这相当于:

    opt map (collection filter) getOrElse collection
    

    【讨论】:

    • 我同意你的解决方案比原始版本更干净,并且可能更适合大型集合、内部循环等,但在这种情况下,它感觉像是过早的优化——这可能是一个操作只发生一次,并且在一个非常小的集合(命令行参数)上,所以我会选择更具表现力的版本。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-02
    • 2016-10-01
    • 2021-12-22
    • 1970-01-01
    • 1970-01-01
    • 2019-09-09
    • 1970-01-01
    相关资源
    最近更新 更多