2013-04-29 88 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這篇文章有很好的總結。

相關問題