2015-04-03 46 views
10

有Scala中类似的东西条件地图功能

condition ? first_expression : second_expression; 

,我可以在斯卡拉地图功能中使用? 我希望能够写出这样的事:

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

如果内联函数是不可能的,我怎么能写之内地图的条件?

回答

2

可以过滤和然后映射等,

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

这是_not_接近解决问题的首选方式。它会导致过滤的项目遍历两次;过滤器的所有项目都会通过,然后再次成功过滤项目。鉴于过滤器保留了大量清单和大量的百分比,您的解决方案效率也不高。顺便说一句,本的答案的最后一行使用了一个视图,可以移动你的解决方案变得高效。 – chaotic3quilibrium 2016-05-10 00:09:27

19

?操作者,有时也被称为三元运算不是Scala中必要的,因为它是由有规律if-else表达式归入:

val x = if (condition) 1 else 2 

要在map中使用此功能,您可以使用flatMap,然后在的任一侧返回。由于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 2步:

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

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

由于问题标记为[tag:apache-spark],因此'tweets'可能是RDD。在那种情况下,没有'filterNot'方法,并且没有'views'。然而,RDD本质上是懒惰的,所以也不需要'views'。 – 2015-04-04 10:49:07