我发现自己反复编写这段代码:
map[id] = map[id] ? map[id] + newListItem : [newListItem]
是否有更简洁的方法将值初始化为List或添加到现有列表?
答案 0 :(得分:9)
另一种方法是使用Map.withDefault
之类的(以Ted为例):
def map = [:].withDefault { [] }
def id = 'foo'
def newListItem = 'bar'
map[id] << newListItem
assert map[id] == ['bar']
map[id] << newListItem
assert map[id] == ['bar', 'bar']
答案 1 :(得分:3)
使用elvis(?:)运算符稍微简洁一点:
def map = [:]
def id = 'foo'
def newListItem = 'bar'
map[id] = (map[id] ?: []) << newListItem
assert map[id] == ['bar']
map[id] = (map[id] ?: []) << newListItem
assert map[id] == ['bar', 'bar']
虽然如果速度很重要,Kyle的答案会更快一点,因为它没有执行任务步骤(在我的机器上测试了100,000个循环,他的是1.36秒,而我的是1.46秒而原始的是16.54秒)。 / p>
答案 2 :(得分:1)
我不知道一种更简洁的方式,但另一种不太好看的方法是:
if (map[id]) map[id] << newListItem else map[id] = [newListItem]
只是为了踢,我在循环中运行每个语法100,000次迭代:
def m = [:]
for (def i=0; i<100000; ++i) {
//if (m['x']) m['x'] << 'val' else m['x'] = ['val']
m['x'] = m['x'] ? m['x'] + 'val' : ['val']
}
语法的时间结果是:
real 0m45.367s
user 0m47.647s
sys 0m0.712s
此语法的时间结果为:
real 0m3.612s
user 0m5.920s
sys 0m0.252s
每次运行的结果都是一致的。所以我会说这种语法绝对是首选。我认为对哈希条目的不断重新分配正在减慢它的速度。
答案 3 :(得分:0)
@Ted完全钉了它。
就像练习一样,好奇/喜欢冒险的人可能会尝试:
List.metaClass.onMap = { Map m = [:], id->
if(m[id])
m[id] << delegate
else
m[id] = [delegate]
}
def id = 'foo'
Map m = [:]
List l = [1,2,3]
m[id] = l.onMap(m,id)
从那时起,只要你有一个包含列表值的Map,就可以使用List.onMap()来填充。
答案 4 :(得分:0)
您需要使用Groovy 1.8:
def map = [:].withDefault { [] }
这不起作用:
def map = [:[]]