我发现了几种方法来查找两个地图之间的键集差异。但是,我想比较完整的key-> values。
我将两个地图设置为Map[String, Map[String, String]]
所以如果我有两张地图
var source = Map(
"one" -> Map("a" -> "bbb", "b" -> "qww"),
"two" -> Map("b" -> "ccc")
)
var target = Map(
"one" -> Map("a" -> "bbb", "b" -> "qqq", "c" -> "ccc"),
"two" -> Map("b" -> "ccc")
)
我想做类似source - target
获得
的最终输出 Map("one" -> Map("b" -> "qww")
我只关心确保所有source
与target
匹配(因此在示例中,target("one")("c")
是无关紧要的)。我想知道是否可以执行一些漂亮的单行函数来完成此任务,否则,我总是可以回过头来遍历所有函数并手动进行比较。
编辑代码更新-
var differences = new ListBuffer[(String, String)]()
source.foreach{
case (db, tableMap) =>
tableMap.foreach{
case (table, createTable) =>
if(createTable != target(db)(table)){
differences.append((db, table))
}
}
}
答案 0 :(得分:1)
鉴于您的要求,source diff target
(如列表所示)会很好用。通过使用diff
从两个外部Map遍历foldLeft
列表,对源和目标之间的内部Map再次对每个键应用diff
会生成想要的净内部Map:
val source = Map(
"one" -> Map("a" -> "bbb", "b" -> "qww"),
"two" -> Map("b" -> "ccc"),
"three" -> Map("c" -> "xxx")
)
val target = Map(
"one" -> Map("a" -> "bbb", "b" -> "qqq", "c" -> "ccc"),
"two" -> Map("b" -> "ccc"),
"four" -> Map("d" -> "yyy")
)
(source.toList diff target.toList).
foldLeft( Map[String, Map[String,String]]() ){ (acc, x) =>
val corrTargMap = target.getOrElse(x._1, Map[String, String]())
val mapDiff = (x._2.toList diff corrTargMap.toList).toMap
acc + (x._1 -> mapDiff)
}
// res1: scala.collection.immutable.Map[String,Map[String,String]] =
// Map(one -> Map(b -> qww), three -> Map(c -> xxx))
答案 1 :(得分:0)
这有效(没有toList
或toMap
等转换):
s.map{case (x,y)=>(x,y.filter(p=>t.getOrElse(x,Map()).forall(_!=p)))}.filter(_._2!=Map())
在Scala REPL中:
scala> val s = Map(
| "one" -> Map("a" -> "bbb", "b" -> "qww"),
| "two" -> Map("b" -> "ccc"),
| "three" -> Map("c" -> "xxx")
| )
s: scala.collection.immutable.Map[String,scala.collection.immutable.Map[String,String]] = Map(one -> Map(a -> bbb, b ->
qww), two -> Map(b -> ccc), three -> Map(c -> xxx))
scala> val t = Map(
| "one" -> Map("a" -> "bbb", "b" -> "qqq", "c" -> "ccc"),
| "two" -> Map("b" -> "ccc"),
| "four" -> Map("d" -> "yyy")
| )
t: scala.collection.immutable.Map[String,scala.collection.immutable.Map[String,String]] = Map(one -> Map(a -> bbb, b ->
qqq, c -> ccc), two -> Map(b -> ccc), four -> Map(d -> yyy))
scala> s.map{case (x,y)=>(x,y.filter(p=>t.getOrElse(x,Map()).forall(_!=p)))}.filter(_._2!=Map())
res2: scala.collection.immutable.Map[String,scala.collection.immutable.Map[String,String]] = Map(one -> Map(b -> qww), three
-> Map(c -> xxx))