【问题标题】:Condition in map function地图功能中的条件
【发布时间】:2015-06-08 04:38:03
【问题描述】:

在 Scala 中有什么类似的东西,

condition ? first_expression : second_expression;

我可以在 scala 的 map 函数中使用吗? 我希望能够写出这样的东西:

val statuses = tweets.map(status => status.isTruncate? //do nothing | status.getText())

如果内联函数不可用,如何在map 中写条件?

【问题讨论】:

    标签: scala apache-spark spark-streaming map-function


    【解决方案1】:

    ? 运算符,有时称为 三元运算符,在 Scala 中不是必需的,因为它包含在常规的 if-else 表达式中:

    val x = if (condition) 1 else 2
    

    要在map 中使用它,您可以使用flatMap,然后在if-else 的任一侧返回Option。由于Option 可以隐式转换为Iterable,所以效果是列表被展平,Nones 被过滤:

    val statuses = tweets.flatMap(status => if (status.isTruncate) None else Some(status.getText))
    

    这相当于使用map,然后使用flatten

    val statuses = tweets.map(status => if (status.isTruncate) None else Some(status.getText)).flatten
    

    更习惯用法,您可以使用collect,它允许您使用偏函数一步完成filtermap

    val statuses = tweets.collect {
        case status if !status.isTruncate => status.getText
    }
    

    您也可以使用filtermap 分两步完成此操作:

    val statuses = tweets.filterNot(_.isTruncate).map(_.getText)
    

    这里的缺点是这将遍历列表两次,这可能是不可取的。如果你使用view,你可以使用同样的逻辑并且只遍历列表一次:

    val statuses = tweets.view.filterNot(_.isTruncate).map(_.getText)
    

    【讨论】:

    • 由于问题被标记为apache-sparktweets 很可能是一个 RDD。在这种情况下,没有filterNot 方法,也没有views。但是,RDD 本质上是惰性的,因此也不需要views
    • 我们也可以使用withFilter只在map等后续操作中进行过滤。 scala-lang.org/api/current/scala/collection/…
    【解决方案2】:

    你可以过滤然后映射,

      val statuses = tweets.filter(_.isTruncate).map(status=> status.getText())
    

    【讨论】:

    • 不是解决问题的首选方法。它导致过滤后的项目被遍历两次;过滤器的所有项目都通过,然后第二次成功过滤的项目。给定一个很大的列表和与过滤器一起保留的相当大的百分比,您的解决方案也非常低效。顺便说一句,Ben 的答案的最后一行使用了一个可以使您的解决方案变得高效的视图。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-10
    • 2018-09-27
    • 2018-08-06
    • 2015-03-08
    • 1970-01-01
    • 1970-01-01
    • 2011-06-14
    相关资源
    最近更新 更多