如何在不覆盖当前条目的情况下添加多个Groovy映射条目?

kbh*_*ker 13 groovy map

我对Groovy Maps的问题.我一直在寻找一种方法,以编程方式将新条目添加到Groovy映射而不覆盖当前条目.例如

def editsMap = [:]

lineEdits.flag.each 
{ lineEdits_Flag ->
   editsMap.put('FlagId',lineEdits_Flag.id)
   editsMap.put('FlagMnemonic',lineEdits_Flag.mnemonic)
   editsMap.put('Action',lineEdits_Flag.action)   
   println "editsMap: ${editsMap}"
}
Run Code Online (Sandbox Code Playgroud)

第一遍产生这个地图:
editsMap:[FlagId:10001,FlagMnemonic:TRA,Action:review]

但第二遍用:editsMap覆盖第一遍:[FlagId:10002,FlagMnemonic:REB,Action:deny]

我要做的是在一个地图中创建多个条目.我需要我的地图填充这样的东西:

editsMap: [FlagId:10001, FlagMnemonic:TRA, Action:review]
editsMap: [FlagId:10002, FlagMnemonic:REB, Action:deny]
editsMap: [FlagId:10003, FlagMnemonic:UNB, Action:deny]
editsMap: [FlagId:20001, FlagMnemonic:REB, Action:deny]
editsMap: [FlagId:20002, FlagMnemonic:ICD, Action:review]
editsMap: [FlagId:30001, FlagMnemonic:REB, Action:deny]
editsMap: [FlagId:40001, FlagMnemonic:ICD, Action:review]
editsMap: [FlagId:40002, FlagMnemonic:MPR, Action:review]
editsMap: [FlagId:50001, FlagMnemonic:CPT, Action:deny]
editsMap: [FlagId:60001, FlagMnemonic:DTU, Action:deny]
editsMap: [FlagId:70001, FlagMnemonic:ICD, Action:review]
editsMap: [FlagId:70002, FlagMnemonic:MPR, Action:review]
Run Code Online (Sandbox Code Playgroud)

一旦我填充了我的地图,我就需要能够找到某些值来处理消息.我相信我可以使用类似的东西:

def thisValue = appliedEditsMap[FlagId, '10001'] ?: "default"
Run Code Online (Sandbox Code Playgroud)

快速查找.

有人可以帮助我了解如何以编程方式将值添加到Groovy地图而不覆盖地图中已有的值吗?

Wil*_*ill 11

你想要像Guava的MultiMap这样东西:

Multimap<String, String> myMultimap = ArrayListMultimap.create();

// Adding some key/value
myMultimap.put("Fruits", "Bannana");
myMultimap.put("Fruits", "Apple");
myMultimap.put("Fruits", "Pear");
myMultimap.put("Vegetables", "Carrot");

// Getting values
Collection<string> fruits = myMultimap.get("Fruits");
System.out.println(fruits); // [Bannana, Apple, Pear]
Run Code Online (Sandbox Code Playgroud)

这个人做了Multimap的纯Groovy仿真:

class GroovyMultimap {
    Map map = [:]

    public boolean put(Object key, Object value) {
        List list = map.get(key, [])
        list.add(value)
        map."$key" = list
    }
}
Run Code Online (Sandbox Code Playgroud)

您可以在地图操作中使用putAtgetAt用于合成糖.您还可以在地图对象中尝试mixin.

他还将Groovy与Guava的multimap一起使用:

List properties = ['value1', 'value2', 'value3']
Multimap multimap = list.inject(LinkedListMultimap.create()) {
    Multimap map, object ->
    properties.each {
        map.put(it, object."$it")
    }
    map
}
properties.each {
    assertEquals (multimap.get(it), list."$it")
}
Run Code Online (Sandbox Code Playgroud)

  • 你也可以这样做:`[:].withDefault {[]} .with {map - > map.fruit <<'banana'; map.fruit <<'apple'; map.veg <<'胡萝卜'; map}` (5认同)

rif*_*boy 9

几年前我遇到过这个问题,作为另一个网站上类似问题的答案.我找不到它最初来自哪里,所以如果有人知道来源请在这里发布.

LinkedHashMap.metaClass.multiPut << { key, value ->
    delegate[key] = delegate[key] ?: []; delegate[key] += value
}

def myMap = [:]

myMap.multiPut("a", "1")
myMap.multiPut("a", "2")
myMap.multiPut("a", "3")

myMap.each {key, list ->
    println "${key} -> $value.list(",")
}
Run Code Online (Sandbox Code Playgroud)

得到:

a -> 1,2,3
Run Code Online (Sandbox Code Playgroud)

使用注入的multiPut()方法可以实现神奇.


tim*_*tes 5

你也可以这样做:

// Dummy map for testing
lineEdits = [ flag:[
  [id:10001, mnemonic:'TRA', action:'review'],
  [id:10002, mnemonic:'REB', action:'deny'],
  [id:10003, mnemonic:'UNB', action:'deny'],
  [id:20001, mnemonic:'REB', action:'deny'],
  [id:20002, mnemonic:'ICD', action:'review'],
  [id:30001, mnemonic:'REB', action:'deny'],
  [id:40001, mnemonic:'ICD', action:'review'],
  [id:40002, mnemonic:'MPR', action:'review'],
  [id:50001, mnemonic:'CPT', action:'deny'],
  [id:60001, mnemonic:'DTU', action:'deny'],
  [id:70001, mnemonic:'ICD', action:'review'],
  [id:70002, mnemonic:'MPR', action:'review'] ] ]

def editsMap = lineEdits.flag
                        .groupBy { it.id } // Group by id
                        .collectEntries { k, v ->
                          [ k, v[ 0 ] ] // Just grab the first one (flatten)
                        }

assert editsMap[ 60001 ] == [ id:60001, mnemonic:'DTU', action:'deny' ]
Run Code Online (Sandbox Code Playgroud)


all*_*lts 0

您需要将其放入一个类中,然后将该类添加到地图中。据我所知,您的信息是相关的,因此存储一个类是有意义的,除非我遗漏了任何内容

你能做的就是将你的班级定义为

class Flag {

String flagID
String flagMnemonic
String action
}

Now Put your Flag in to your map as

editsMap.put(10000,newFlag(flagID:'10000',flagMnemonic:'TES',action:'tes'))
Run Code Online (Sandbox Code Playgroud)