Groovy列表迭代和Map更新在某些上下文中只使用最后一个元素

chhkpiq4  于 5个月前  发布在  其他
关注(0)|答案(2)|浏览(50)

剥离代码以突出显示演示行为的主要组件:

def template = [type: 'a', directories: [['dir': 'a/b/c']]]
def ids = [1,2,3]
def allPhases = []

ids.each { id ->
    def phase = [:]
    template.keySet().each { phase.put(it, template.get(it)) }
    phase.id = id
    phase.directories[0].put('command', "apply/${id}")
    allPhases.add(phase)
}
println(allPhases)

字符串
输出量:

[
    [type:a, directories:[[dir:a/b/c, command:apply/3]], id:1],
    [type:a, directories:[[dir:a/b/c, command:apply/3]], id:2],
    [type:a, directories:[[dir:a/b/c, command:apply/3]], id:3]
]


我有一个模板和一个我要迭代的值列表。(未显示)向map中的键添加元素。我看到在每次迭代中,map中的键id都被正确设置,但向现有的map列表添加键会导致问题-它只使用ids的最后一个值(例如3)。
为什么某些键会发生这种情况,而其他键却没有?Map列表的更新需要以不同的方式完成吗?

yzuktlbb

yzuktlbb1#

你总是在写同一个数组,因为你的map的“副本”只复制了map的 * 结构 *,而没有复制它的内容。directories的 * 值 * 不是 * 复制的 *,而是 * 引用的 *。
看看其中一个答案,如何做一个深复制,并找到一种你喜欢的方式(或只是解决问题的directories你自己。例如Deep Copy

import groovy.json.*

def template = JsonOutput.toJson(
        [type: 'a', directories: [['dir': 'a/b/c']]]
        )
def cloner = new JsonSlurper()

def ids = [1,2,3]
def allPhases = ids.collect { id ->
    cloner.parseText(template).tap{
            put('id', id)
            directories[0].put('command', "apply/${id}")
    }
}
println(allPhases)

字符串

1cklez4t

1cklez4t2#

下面这一行:

phase.directories[0].put( 'command', "apply/${id}")

字符串
重写Map到名为command的键的值。因此,在迭代123之后,每次只保留最后一个值。只是为了检查,让我们通过将其更改为以下内容来使每次迭代的键唯一:

phase.directories[0].put( "command-${id}", "apply/${id}")


然后输出将是这样的:

[type:a, directories:[[dir:a/b/c, command-1:apply/1, command-2:apply/2, command-3:apply/3]], id:1]
[type:a, directories:[[dir:a/b/c, command-1:apply/1, command-2:apply/2, command-3:apply/3]], id:2]
[type:a, directories:[[dir:a/b/c, command-1:apply/1, command-2:apply/2, command-3:apply/3]], id:3]

相关问题