2013-04-29 45 views
2

我有一个方法load,这是相对昂贵的调用。为了在加载期间允许某种异常处理,返回Try。我现在需要一个针对loadAll方法的实现,该方法对于给定的每个键基本上委托load。这是我的第一个方法,但是我不知道这是否与Try有关的最佳实践。有没有更好的方法来实现以下目标?Iterable [尝试[(K,V)]]尝试[地图[K,V]]

def load(key: K): Try[V] // very expensive 

def loadAll(keys: Traversable[K]): Try[Map[K, V]] = { 

    // remove duplicate keys 
    val ukeys = Set.empty ++ keys 

    val result: Iterable[Try[(K, V)]] = ukeys map { key => 
    load(key) match { 
     case Success(value)  => Success(key, value) 
     case Failure(exception) => Failure(exception) 
    } 
    } 

    Try(result.map { _.get }.toMap) 
} 

回答

2

这是一个一行在香草斯卡拉(假设你已经有了范围Try):

def loadAll(keys: Traversable[K]) = Try{ keys.toSet.map((k: K) => (k,load(k).get)).toMap } 
+0

谢谢!它应该被映射为'Tuple [K,V]'作为'(k,load(k).get)'。我是对的,它迭代了3次以上的键(toSet','map'和'toMap')? – 2013-04-30 05:59:55

+0

@ManuelSchmidt - 我已经调整了答案以返回一个元组。这在键上重复三次;如果'load'昂贵,那么你不关心,因为'load'主宰了所有其他的捣蛋。 – 2013-04-30 14:22:20

4

你可以做到这一点使用折叠遍历键,以及用于理解到Try实例相结合:

def toSet(keys: Traversable[K]): Try[Map[K, V]] = { 
    keys.toSet.foldLeft(Try(Map.empty[K, V])){ case (tryMap, key) => 
    for (m <- tryMap; v <- load(key)) yield m.updated(key, v) 
    } 
} 
+0

谢谢!工作,但我不得不稍微改变它,因为'Traversable'似乎不可用'distinct' – 2013-04-30 06:01:18

+0

固定(用'toSet'替换'distinct')。 – 2013-04-30 09:53:25

2

如果你有兴趣在scalaz的解决方案,这是一个一般操作,可通过Traversable仿函数,称为sequenceTry需要的实例驻留在scalaz-contrib。下面是它看起来像:

Welcome to Scala version 2.10.1 (OpenJDK 64-Bit Server VM, Java 1.7.0_21). 
Type in expressions to have them evaluated. 
Type :help for more information. 

scala> import scalaz._, Scalaz._, scalaz.contrib.std.utilTry._ 
import scalaz._ 
import Scalaz._ 
import scalaz.contrib.std.utilTry._ 

scala> import scala.util.Try 
import scala.util.Try 

scala> val result: Iterable[Try[(Int, String)]] = Iterable.empty 
result: Iterable[scala.util.Try[(Int, String)]] = List() 

scala> result.toList.sequence.map(_.toMap) 
res0: scala.util.Try[scala.collection.immutable.Map[Int,String]] = Success(Map()) 

顺便说一句,有一个纸"The essence of the Iterator pattern",描述/导出traverse(和sequence,因为它的特殊情况)。这里有Eric Torreborre这篇文章有很好的总结。

相关问题