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) } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |