在 groovy 中创建一个新的动态命名列表

Create a new dynamically named list in groovy

我有一个看起来像这样的项目列表 items = ["a", "b", "c"]

我还有一个值列表,看起来像这样 values = ["a1", "a2", "a3", "b1", "b2", "c1", "c2", "c3"]

我的 items 列表是静态的,但我的 values 列表会经常变化。

我的代码是这样的

for(z=0;z<items.size();z++){
    for(i=0;i<values.size();i++){
        if(values[i] =~ items[z]){
            println value[i]
        } 
    }

我真正想做的是将 value[i] 添加到名称为 items[z] 的列表中,其功能类似于 ${"items[i]"} += value[i],代码会将其读取为 a += value[1]b += value[1] 依此类推,所以最后我可以做这样的事情

assert a == ["a1", "a2", "a3"]
assert b == ["b1", "b2"]
assert c == ["c1", "c2", "c3"]

是否可以像这样动态命名变量?

据我理解代码应该是这样的:

def map = [:]
for(z=0;z<items.size();z++){
    for(i=0;i<values.size();i++){
        if(values[i] =~ items[z]){
            if (map[values[i]] == null) {
                map[values[i]] = []
            }
            map[values[i]].add(items[z])
        } 
    }
}

assert map[values[0]] == ["a1", "a2", "a3"]
assert map[values[1]] == ["b1", "b2"]
assert map[values[2]] == ["c1", "c2", "c3"]

您可以动态添加变量,但您需要使用 this(作为您设置变量的对象的实例),例如:

this."${items[i]}" += value[i]

这应该能满足您的需求,或者至少能为您指明正确的方向。

如果您接受输出将是 Map 的事实,这里是另一种基于 eachfindAll 闭包的方法:

def items = ["a", "b", "c"]
def values = ["a1", "a2", "a3", "b1", "b2", "c1", "c2", "c3"]

def result = [:]
items.each{i->
    result.put(i, values.findAll{v->v.startsWith(i)})
}
println result; //[a:[a1, a2, a3], b:[b1, b2], c:[c1, c2, c3]]

groupBy是你的朋友:

def groups = values.groupBy { v -> 
  items.find { i -> v =~ i } 
}
assert groups.a == ['a1', 'a2', 'a3']
assert groups.b == ['b1', 'b2']
assert groups.c == ['c1', 'c2', 'c3']

作为旁注,我强烈建议您 Groovy's excellent List/Map comprehension 仔细看看;我可以保证,一旦您明白了,您将不再需要在代码中使用 for 循环。