假设我是这样的scala地图 -
Map[String, List[String]] = Map(
"A"->List(1,2,3),
"B"->List(2,4),
"C"->List(4,5),
"D"->List(7,8,9),
"E"->List(8,9),
"F"->List(4,5,7),
"G"->List(1,3,2)
)
我想将键分组,使得它们的交集不为空。例如,结果应该是 -
Map(
List("A","B","G")->List(2),
List("C","F")->List(4,5),
List("D","E")->List(8,9)
)
请注意,可以有多个输出,例如可以有List(" B"," C") - > List(4)。我只需要选择任何人,只要所有的钥匙都存在且钥匙不应重复,例如 - ' B'和' C'即使我们仍然发现任何交叉对不是空的,所以在地图中已经存在,例如我们发现' B'和' C',我们不应该添加它。 我解决这个问题的方法包括将值列表转换为集合,然后遍历映射的所有条目,使其继续将其值与下一个值相交,如果交集不为空,我们将对键进行分组。
但我想知道是否有其他办法可以做到这一点。
编辑 -
重点是密钥列表应该是大的,其值应该至少有一个元素。
答案 0 :(得分:2)
我将Map的值转换为List[Int]
只是为了让它更容易加载到IDE中。这很容易被撤消。
val m :Map[String, List[Int]] = Map(
"A"->List(1,2,3),
"B"->List(2,4),
"C"->List(4,5),
"D"->List(7,8,9),
"E"->List(8,9),
"F"->List(4,5,7),
"G"->List(1,3,2))
然后我fold
在键上查看哪些intersect
。
m.keys.foldLeft(List.empty[(List[String],List[Int])]){case (acc,k) =>
val (not, has) = acc.partition(_._2.intersect(m(k)).isEmpty)
has.headOption.fold((List(k),m(k)) :: acc){case (s,v) =>
(k::s, v.intersect(m(k))) :: has.tail ::: not
}
}.toMap
//res0: Map[List[String],List[Int]] = Map(List(D, E) -> List(8, 9)
// ,List(C, F) -> List(4, 5)
// ,List(B, G, A) -> List(2))
这是一种蛮力的"方法,为partition()
获取交集一次,并在构建累加器的新条目时再次获取交集,并为每个m
值多次取消引用原始地图k
。
<强>解释强>
从地图键中我建立List
个(List[String],List[Int])
元组。对于每个Map键,累积列表在那些与新键值(has
)相交的元素和没有交集(not
)的元素之间进行分区。
我只抓取has
组中的第一个元素。如果没有,则此键及其值将添加到结果前面,否则键将添加到has.head
键列表中,并调整值列表以反映当前的交集。该新元素预先添加到has.tail
(被忽略的交叉点)并与not
列表中的所有内容结合使用。
答案 1 :(得分:0)
您可以按照此方法获得所需的输出。
假设您输入了以下格式。
val map1: Map[String, List[Int]] = Map(
"A"->List(1,2,3),
"B"->List(2,4),
"C"->List(4,5),
"D"->List(7,8,9),
"E"->List(8,9),
"F"->List(4,5,7)
)
要获取唯一值,我们将值列表转换为集合,以便我们得到值之间的交集
val map2 = map1.map(x => (x._1,x._2.toSet))
val result: Map[List[String], Set[Int]] =
for(a <- map2;
b <- map2 if( (a._1!=b._1) && (a._2 intersect b._2).nonEmpty))
yield( List(a._1,b._1) -> (a._2 intersect b._2) )
此功能将为您提供结果
result: Map[List[String],Set[Int]] = Map(List(D, F) -> Set(7), List(C, F) -> Set(4, 5), List(E, D) -> Set(8, 9), List(B, C) -> Set(4), List(B, A) -> Set(2), List(A, B) -> Set(2), List(F, C) -> Set(4, 5), List(C, B) -> Set(4), List(D, E) -> Set(8, 9), List(F, D) -> Set(7), List(F, B) -> Set(4), List(B, F) -> Set(4))
如果您对此方法有任何疑问,请与我们联系。感谢