初始化/添加作为Groovy中的列表的Map值的最佳方法

时间:2011-05-25 03:39:28

标签: groovy

我发现自己反复编写这段代码:

map[id] = map[id]  ?  map[id] + newListItem : [newListItem]

是否有更简洁的方法将值初始化为List或添加到现有列表?

5 个答案:

答案 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 = [:[]]