合并两个没有重复项的映射列表的映射。

huangapple go评论83阅读模式
英文:

Merge two maps of maps of lists with no duplicates

问题

我有两个地图,想要将它们的“读/写”权限合并 - 将其中的 2 个地图合并成一个

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", "write5"]]]

结果应该类似于这样

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

英文:

I've got two maps and would like to combine their 'read/write' priviliges - 2 maps inside it into one

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"]]]

So that result would be something like this

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

merging all lists and removing duplicates


As to what I've made, took like 2hrs and few posts/forums I've read and I'm stuck in this part

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;
}

with https://www.baeldung.com/groovy-maps as source

答案1

得分: 2

不确定 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;
}));
英文:

Not sure about groovy, but in java it would be something like:

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

here is the java code i tested (before you posted your code)

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

答案2

得分: 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]]]
英文:

You can try below function to merge two map with lists,

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

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

merge(a, b)

Output:

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

huangapple
  • 本文由 发表于 2020年10月16日 14:52:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/64384257.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定