Best way to initialize / add map values ​​that are listed in Groovy

I find that I am writing this code repeatedly:

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

Is there a shorter way to initialize a value as a list or add to an existing list?

+3
source share
5 answers

An alternative would be to use Map.withDefaultas it was (taking the Ted example):

def map = [:].withDefault { [] }
def id = 'foo'
def newListItem = 'bar'

map[id] << newListItem

assert map[id] == ['bar']

map[id] << newListItem

assert map[id] == ['bar', 'bar']
+9
source

Using the elvis (? :) operator is a bit more concise:

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

Although, if speed is important, Kyle’s answer is a little faster, since he does not complete the assignment step (100,000 cycles were checked on my machine, its 1.36 s, and I have 1.46 s against 16.54 for the original).

+3
source

, , :

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

The results were consistent between several runs of each. Therefore, I would say that this syntax is definitely preferable. I think the constant reassignment of the hash record is what slows it down.

+1
source

@Ted completely nailed it.

As an exercise, the curious / adventurous can try:

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)

From now on, at any time you have a map containing the values ​​of the list, you can use List.onMap () to fill.

0
source

You need Groovy 1.8:

def map = [:].withDefault { [] }

This will not work:

def map = [:[]]
0
source

All Articles