2011-06-02 19 views
2

假设我们有一个按照某种顺序排序的值列表。我们也有映射到这些值的元素映射。我们希望以与键列表中列出的键相同的顺序从地图中获取元素集合。一个简单的方法是:如何根据某种方法的结果收集一个集合的元素?

val order = Seq("a", "b", "c") 
val map = Map("a" -> "aaa", "c" -> "ccc") 

val elems = order.map(map.get(_)).filter(_.isDefined).map(_.get) 

但是,程序需要迭代集合三次。是否有可能更高效地实现此功能?特别是用收集方法可以做到这一点吗?

+0

isDefined仅仅是一个示例。我想用各种方法进行过滤。换句话说,我正在寻找一种通过单次迭代进行映射与过滤的方法。 – 2011-06-02 13:49:40

回答

1

更一般地说,你可以使用视图;那么该集合仅迭代一次,并且所有三个操作都按照您的要求应用:

order.view.map(map.get).filter(_.isDefined).map(_.get).force 
+0

所有的解决方案都很好,但这是最通用的我。 – 2011-06-03 12:44:56

3

那么,一个标准的Scala地图也是一个PartialFunction,所以你可以使用“collect”。

val elems = order.collect(map) 
+0

好吧,那么一些数据源呢,我们有一个getById方法返回Option? – 2011-06-02 14:00:27

+0

你可以通过这种方法flatMap ... – 2011-06-02 14:50:29

1

你可以使用flatMap。这里有一个例子:

List(1,2,3,4,5).flatMap(x => if (x%2 == 1) Some(2*x) else None) 

如果它的基础上Option回报这相当于

List(1,2,3,4,5).filter(_%2==1).map(2*) 
2

,那么这个工程:

order flatMap (map get) 

虽然,当然,order collect map是在这个特定的例子中足够了

相关问题