合并两个列表的地图,没有重复的地图

时间:2020-10-16 06:52:59

标签: java groovy

我有两张地图,想将他们的“读/写”特权-里面的两张地图合并为一个

myMap1 = ["app1": ["user1": ["read1", "write1"], 
                   "user2": ["read1"]], 
         "app2": ["user1": ["read1", "write1"],
                  "user2": ["read1", "write1"]]]
myMap2 = ["app1": ["user1": ["read2", "write2"], 
                   "user2": ["read2"]], 
         "app2": ["user1": ["read2", "write2"],
                  "user2": ["read2", "write2"],
                  "user3": ["read5", "read5"]]]

所以结果将是这样

finalMap = ["app1": ["user1": ["read1", "write1", "read2", "write2"],
                     "user2": ["read1", "read2"]],
            "app2": ["user1": ["read1", "write1", "read2", "write2"],
                     "user2": ["read2", "write2"],
                     "user3": ["read5", "write5"]]]

合并所有列表并删除重复项


关于我所做的事情,花了大约2个小时的时间,我读了一些帖子/论坛,但仍停留在这一部分

String[] all_users = ["usera", "userb", "userc", "leada", "leadb"]
String[] only_priv_users = ["leada", "leadb"]

String[] read_perm = ["read", "write"]
String[] full_perm  = ["read", "write", "build"]

String[] deploy_actions = ["deploy"]
String[] release_actions = ["delete", "release"]

String[] all_apps = ["app1", "app2", "app3", "app4"]

def firstMap = [:]
def secondMap = [:]
def resultMap = [:]

for(app in all_apps){
    for(deploy_action in deploy_actions){
            firstMap[app] = all_users.collectEntries{[(it): deploy_action]}
    }
    for(release_action in release_actions){
            secondMap[app] = only_priv_users.collectEntries{[(it): release_action]}
    }
}

resultMap = additionJoin(firstMap , secondMap)

for(a in resultMap){
    println("App priviliges: " + a)
​}


Map additionJoin( Map firstMap, Map secondMap ){
  def resultMap = [:];
  resultMap.putAll( firstMap );   
  resultMap.putAll( secondMap );

  resultMap.each { key, value ->
    if( firstMap[key] && secondMap[key] )
    {
      resultMap[key] = firstMap[key] + secondMap[key]
    }
  }
  return resultMap;
}​

https://www.baeldung.com/groovy-maps作为来源

2 个答案:

答案 0 :(得分:1)

您可以尝试使用以下功能将两个地图与列表合并,

def a = ["app1": ["user1": ["read1", "write1"], "user2": ["read1"]], "app2": ["user1": ["read1", "write1"], "user2": ["read1", "write1"]]];
def b = ["app1": ["user1": ["read2", "write2"], "user2": ["read2"]], "app2": ["user1": ["read2", "write2"], "user2": ["read2", "write2"], "user3": ["read5", "read5"]]]

def merge(Map lhs, Map rhs) {
    return rhs.inject(lhs.clone()) {
        map, entry ->
if (map[entry.key] instanceof Map && entry.value instanceof Map) {
            map[entry.key] = merge(map[entry.key], entry.value)
        } else if (map[entry.key] instanceof Collection && entry.value instanceof Collection) {
            map[entry.key] += entry.value
        } else {
            map[entry.key] = entry.value
        }
        return map
    }
}

merge(a, b)

输出:

[app1:[user1:[read1, write1, read2, write2], user2:[read1, read2]], app2:[user1:[read1, write1, read2, write2], user2:[read1, write1, read2, write2], user3:[read5, read5]]]

答案 1 :(得分:1)

不确定groovy,但是在Java中,它将类似于:

myMap2.forEach((k,v) -> myMap1.merge(k,v, (u,t) -> {
        t.forEach((g,h) -> u.merge(g,h, (i,j) -> {
            i.addAll(j);
            return i;
        }));
        return u;
    }));

这是我测试过的Java代码(在发布代码之前)

    Map<String, Map<String, Set<String>>> myMap1 = new HashMap<>();
    Map<String, Set<String>> subFirst = new HashMap<>();
    subFirst.put("user1", new HashSet<String>(){{add("read");}});
    subFirst.put("user2", new HashSet<String>(){{add("read");add("write");}});
    myMap1.put("app1", subFirst);
    Map<String, Map<String, Set<String>>> myMap2 = new HashMap<>();
    Map<String, Set<String>> subSecond = new HashMap<>();
    subSecond.put("user1", new HashSet<String>(){{add("write");}});
    subSecond.put("user2", new HashSet<String>(){{add("full");}});
    myMap2.put("app1", subSecond);
    myMap2.forEach((k,v) -> myMap1.merge(k,v, (u,t) -> {
        t.forEach((g,h) -> u.merge(g,h, (i,j) -> {
            i.addAll(j);
            return i;
        }));
        return u;
    }));