加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Scala:从元组列表构建一个Map,但如果存在矛盾的条目则会失败

发布时间:2020-12-16 19:01:57 所属栏目:安全 来源:网络整理
导读:我认为这可能是一种常见的操作.所以也许它在API内部,但我找不到它.如果没有,我也对有效的功能/简单解决方案感兴趣. 给定一系列元组(“a” – 1,“b” – 2,“c” – 3)我想把它变成一个映射.使用TraversableOnce.toMap很容易.但是,如果结果地图“将包含矛盾
我认为这可能是一种常见的操作.所以也许它在API内部,但我找不到它.如果没有,我也对有效的功能/简单解决方案感兴趣.

给定一系列元组(“a” – > 1,“b” – > 2,“c” – > 3)我想把它变成一个映射.使用TraversableOnce.toMap很容易.但是,如果结果地图“将包含矛盾”,即分配给同一个键的不同值,我想要使这种结构失败.类似于序列(“a” – > 1,“a” – > 2).但是应该允许重复.

目前我有这个(非常迫切的)代码:

def buildMap[A,B](in: TraversableOnce[(A,B)]): Option[Map[A,B]] = {
  val map = new HashMap[A,B]
  val it = in.toIterator
  var fail = false
  while(it.hasNext){
    val next = it.next()
    val old = map.put(next._1,next._2)
    fail = old.isDefined && old.get != next._2
  }

  if(fail) None else Some(map.toMap)
}

边问题

最终的toMap真的有必要吗?省略它时会出现类型错误,但我认为它应该有效. toMap的实现构造了一个我想避免的新映射.

解决方法

与使用Seq [A]时一样,最佳解决方案性能取决于具体的集合类型.
一般但不是非常有效的解决方案是折叠选项[Map [A??,B]]:

def optMap[A,B](in: Iterable[(A,B]] = 
  in.iterator.foldLeft(Option(Map[A,B]())) {
    case (Some(m),e @ (k,v)) if m.getOrElse(k,v) == v => Some(m + e)
    case _ => None
  }

如果您限制自己使用List [A,B],则优化版本将为:

@tailrec
def rmap[A,B](in: List[(A,B)],out: Map[A,B] = Map[A,B]()): Option[Map[A,B]] = in match {
  case (e @ (k,v)) :: tail if out.getOrElse(k,v) == v =>
    rmap(tail,out + e)
  case Nil =>
    Some(out)
  case _ => None
}

另外,使用可变映射的不太惯用的版本可以像这样实现:

def mmap[A,B]] = {
  val dest = collection.mutable.Map[A,B]()

  for (e @ (k,v) <- in) {
    if (dest.getOrElse(k,v) != v) return None
    dest += e
  }

  Some(dest.toMap)
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读