如何添加,而不覆盖当前的条目多Groovy的映射条目?(How do I add multiple

2019-08-18 00:52发布

我用Groovy地图问题。 我一直在寻找一种方法以编程方式添加新条目到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}"
}

第一遍产生此地图:
editsMap:FlagId:10001,FlagMnemonic:TRA,动作:评论]

但在第二遍覆盖第一遍与:editsMap:[FlagId:10002,FlagMnemonic:REB,动作:拒绝]

我想要做的就是创建一个地图内的多个条目。 我需要我的地图来填充是这样的:

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]

一旦我已填充我的地图,然后我需要能够以处理信息来寻找某些价值观。 我相信,我可以使用类似:

def thisValue = appliedEditsMap[FlagId, '10001'] ?: "default"

做一个快速查找。

有人可以帮助我了解如何编程值添加到Groovy的地图,而在地图已经覆盖值?

Answer 1:

你要像番石榴的多重映射 :

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]

这家伙让Multimap之的纯Groovy的仿真:

class GroovyMultimap {
    Map map = [:]

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

您可以使用putAtgetAt在地图操作语法糖。 你也可以尝试混入在地图对象。

他还使用Groovy中使用番石榴的多重映射:

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")
}


Answer 2:

我碰到这个几年前来到作为一个答案,在其他网站上类似的问题。 我找不到它最初来自因此,如果有人知道源请在这里发表它来了。

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(",")
}

得到:

a -> 1,2,3

使用注射multiPut()方法确实神奇。



Answer 3:

你也可以做这样的事情:

// 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' ]


Answer 4:

如果你想要做的事情多重映射无需外部类,你可以存储地图列表,而不是,语法也不会很麻烦或任何东西。

def editsMap = [:].withDefault{[]} lineEdits.flag.each { lineEdits_Flag -> editsMap.FlagId << lineEdits_Flag.id editsMap.FlagMnemonic << lineEdits_Flag.mnemonic editsMap.Action << lineEdits_Flag.action println "editsMap: ${editsMap}" }或者,如果你真的首选原来的语法,它看起来像: editsMap.get('FlagId').add(lineEdits_Flag.id)甚至可以这样: editsMap.get('FlagId') << lineEdits_Flag.id这种解决方案的优势在于,它往往是比较明显的,你在做什么?比如它不是一个魔图是单品转换成一个列表(这不是标准地图的合同),但它始终是一个地图的,你只是作为一个地图列表的使用列表。

在不用彷徨总是工作描述的多重映射以同样的方式 - 它总是会返回列表中的映射项。



Answer 5:

地图是一组键 - 值映射关系,你在不同的值,通过插入钥匙,让你可以使用密钥后找到他们。 您的例子中值相同的密钥遍地堵塞。 你需要选择的唯一密钥。

使一些类来存储你的价值观在地图上一个条目:

class Stuff {
    String flagMnemonic
    String action
}

做一个地图,您将使用flagId作为关键(因为这是你如何识别标志唯一)和东西的价值(因为这是你想要查找的数据)。

def editsMap = [:] 

如果您在此处使用类型声明,如果flagId是一个字符串,地图的类型将Map<String, Stuff>

现在你可以把东西放在地图:

lineEdits.flag.each { lineEdits_Flag -> 
    editsMap[lineEdits_Flag.id] = 
    new Stuff(
        flagMnemonic: lineEdits_Flag.mnemonic, 
        action: lineEdits_Flag.action) 
}

并把它背出来与

def myStuffFor10001 = editsMap['10001']
println myStuffFor10001.flagMnemonic // should equal 'TRA'
println myStuffFor10001.action // should equal 'review'

也有一个简单的替代使用?: "default"设置默认值,你可以使用withDefault创建地图时:

def defaultStuff = new Stuff(
    flagMnemonic: "defaultMnemonic", action:"defaultAction")
def editsMap = [:].withDefault { defaultStuff }

所以,每当你从地图中不存在有问的东西,你指定的默认对象。



Answer 6:

为什么不使用像列表和关闭:

editsList = [
[FlagId:10001, FlagMnemonic:TRA, Action:review],
[FlagId:10002, FlagMnemonic:REB, Action:deny],
[FlagId:10003, FlagMnemonic:UNB, Action:deny],
[FlagId:20001, FlagMnemonic:REB, Action:deny],
[FlagId:20002, FlagMnemonic:ICD, Action:review],
[FlagId:30001, FlagMnemonic:REB, Action:deny],
[FlagId:40001, FlagMnemonic:ICD, Action:review], 
[FlagId:40002, FlagMnemonic:MPR, Action:review],
[FlagId:50001, FlagMnemonic:CPT, Action:deny],
[FlagId:60001, FlagMnemonic:DTU, Action:deny],
[FlagId:70001, FlagMnemonic:ICD, Action:review],
[FlagId:70002, FlagMnemonic:MPR, Action:review]
]
def appliedEditsMap = {property,idValue->
     return editsList.find{it[property] == idValue}
}
def thisValue = appliedEditsMap(FlagId, '10001') ?: "default"


Answer 7:

你需要把这个一类,然后添加类的地图。 从我看到你的信息涉及所以有一类存储是有道理的,除非我失去了什么

你可以做的是定义为类

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'))


文章来源: How do I add multiple Groovy map entries without overwriting the current entries?
标签: map groovy