简体   繁体   English

可尝试[尝试[(K,V)]]尝试[Map [K,V]]

[英]Iterable[Try[(K, V)]] to Try[Map[K, V]]

I have a method load which is relatively expensive to call. 我有一个方法load调用相对昂贵。 In order to allow some kind of exception handling during loading it returns a Try . 为了在加载过程中允许某种异常处理,它返回一个Try I need now an implementation for the loadAll method which basically delegates to load for each of the given keys. 我现在需要一个loadAll方法的实现,它基本上委托load每个给定的键。 Here is my first approach, however I don't know if this is best practices with respect to the work with Try . 这是我的第一种方法,但是我不知道这是否是关于Try的工作的最佳实践。 Is there a better way to achieve the following? 有没有更好的方法来实现以下目标?

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)
}

You can do this using a fold to iterate over the keys, and a for comprehension to combine the Try instances: 您可以使用折叠来迭代键,然后使用comp来组合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 )
  }
}

If you're interested in a scalaz solution, this is a general operation, available via Traversable functors, called sequence . 如果您对scalaz解决方案感兴趣,这是一个通用操作,可通过Traversable仿函数获得,称为sequence Needed instances for Try reside in scalaz-contrib . Try驻留在scalaz-contrib中需要的实例。 Here's how it might look like: 这是它的样子:

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())

By the way, there's a paper "The essence of the Iterator pattern" , describing/deriving traverse (and sequence , as it's special case). 顺便说一下,有一篇论文“迭代器模式的本质” ,描述/导出traverse (和sequence ,因为它是特殊情况)。 There's a great summary of this paper by Eric Torreborre here. Eric Torreborre在这里有一篇很好的总结。

这是一个香草Scala的单行(假设你已经Try了范围):

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 将Map [K,Option [V]]转换为Map [K,V]的更好方法 - Better way of converting a Map[K, Option[V]] to a Map[K,V] 将RDD [(K,V)转换为Map [K,List [V]] - Convert RDD[(K,V) to Map[K,List[V]] Scala:如何从Set [K]和从K到V的函数创建Map [K,V]? - Scala: How to create a Map[K,V] from a Set[K] and a function from K to V? 如何使用 Circe 对 Map[K,V] 进行编码 - How to Encode Map[K,V] using Circe 如何使用Map([K,V])而不是Map [K,V]创建Map构造函数? - How to create a Map constructor using Map([K,V]) instead of Map[K,V]? 在使用RDD的Scala中,如果RDD [(k,Iterable [v]),如何在Iterable中获得Apply函数 - in Scala using RDD , how do you get apply function in the Iterable if RDD[(k,Iterable[v]) 如何通过解析 CSV 文件来创建 Map[K, V] 和 Seq[A]? - How to create Map[K, V] and Seq[A] by parsing CSV file? map.updated(k,v)和map +(k,v)之间*有任何区别吗? 我在一个而不是另一个上遇到编译错误 - Is there *any* difference between map.updated(k,v) and map + (k,v)? I'm getting a compile error on one but not the other RDD [(K,V)]是rdd中的一种类型:RDD [(K,V)]? - is RDD[(K, V)] a type in rdd: RDD[(K, V)]? 读取一个文件作为Map(K,V)并通过V作为键,同时读取第二个文件作为Map - Reading one file as Map(K,V) and pass V as keys while reading the second file as Map
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM