简体   繁体   English

scala foldLeft与地图地图

[英]scala foldLeft with map of maps

I have a Map which is like 我有一张像

val v = Map("A" -> Map("C" -> "D", "F" -> "G"), "B" -> Map("C" -> "E", "M" -> "N"))

I have to create new map which will have list of value maps and their parents, so my resultant map will look like 我必须创建一个新地图,其中将包含价值地图及其父母的列表,所以我生成的地图看起来像

Map("C" -> List(Map("A" -> Map("C" -> "D", "F" -> "G"), "B" -> Map("C" -> "E", "M" -> "N")), "F" -> List(Map("A" -> Map("C" -> "D", "F" -> "G")), "M" -> List("B" -> Map("C" -> "E", "M" -> "N")))

can this be possible with foldleft. foldleft可以做到吗? I know this is confusing but any help will be appreciated. 我知道这很令人困惑,但是任何帮助将不胜感激。

Yes, it can be done with a foldLeft . 是的,可以使用foldLeft完成。

I don't know why you have Lists in there, because each List has exactly one Map as an element. 我不知道为什么要在其中添加列表,因为每个List中只有一个Map作为元素。 Not more, not less. 不多不少。

Anyways. 无论如何。

I use the fold over the values (which are the maps) of v , so I can access the keys of those maps faster. 我使用vvalues (即映射)的折叠,以便可以更快地访问那些映射的keys I throw away all keys which are already in acc , so there won't be any duplicate computation. 我丢弃了所有已经在acc keys ,因此不会有重复的计算。 ( elem.keys.filter(!acc.isDefinedAt(_)) ). elem.keys.filter(!acc.isDefinedAt(_)) )。

Then for each key that is not yet in our result acc , traverse the original v and look where it occurs as a key in the value maps. 然后,对于尚未出现在结果acc每个key ,遍历原始v并查看其在值映射中作为key的位置。 ( v.filter{case (k, map) => map.isDefinedAt(key)}) ) v.filter{case (k, map) => map.isDefinedAt(key)})

Then put the filtered maps in a List and add them with their corresponding keys to acc . 然后将过滤后的地图放入列表中,并将其及其对应的键添加到acc

Side note : maps of maps, keys of values, keys, values ... I'm not sure how I can explain this better without even confusing myself... I don't even know what I should highlight.. 旁注地图,值的键,键,值...我不确定如何才能更好地解释这一点,甚至不会混淆自己...我什至都不知道该突出显示什么。

val v = Map("A" -> Map("C" -> "D", "F" -> "G"), "B" -> Map("C" -> "E", "M" -> "N"))

val result = v.values.foldLeft(Map.empty[String, List[Map[String, Map[String, String]]]])((acc, elem) => {
 val nextEntries = elem.keys.filter(!acc.isDefinedAt(_)).map(key => 
   key -> List(v.filter{case (k, map) => map.isDefinedAt(key)}))
 acc ++ nextEntries
})

println(result) //Map(C -> List(Map(A -> Map(C -> D, F -> G), B -> Map(C -> E, M -> N))), F -> List(Map(A -> Map(C -> D, F -> G))), M -> List(Map(B -> Map(C -> E, M -> N))))

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM