tags:

views:

103

answers:

3

In python, I can do the following:

keys = [1, 2, 3]
values = ['a', 'b', 'c']
d = dict(zip(keys, values))

assert d == {1: 'a', 2: 'b', 3: 'c'}

Is there a nice way to construct a map in groovy, starting from a list of keys and a list of values?

+2  A: 

Try this:

def keys = [1, 2, 3]
def values = ['a', 'b', 'c']
def pairs = [keys, values].transpose()

def map = [:]
pairs.each{ k, v -> map[k] = v }
println map

Alternatively:

def map = [:]
pairs.each{ map << (it as MapEntry) }
NullUserException
Very nice, it looks like `transpose()` is equivalent to python's `zip()`. Now if only there was a Map constructor for a list of pairs. `[:].putAll(pairs.collect{ new MapEntry(it[0], it[1]) })` works as a one-liner, but is uglier than I'd like.
ataylor
@ataylor See my updated post for another way to use `MapEntry`
NullUserException
`[keys,values].transpose().inject([:]) { map, it -> map << ( it as MapEntry ) }`
tim_yates
+2  A: 

There isn't anything built directly in to groovy, but there are a number of ways to solve it easily, here's one:

def zip(keys, values) {
    keys.inject([:]) { m, k -> m[k] = values[m.size()]; m } 
}

def result = zip([1, 2, 3], ['a', 'b', 'c'])
assert result == [1: 'a', 2: 'b', 3: 'c']
Ted Naleid
+1  A: 

There's also the collectEntries function in Groovy 1.8 (currently in beta)

def keys = [1, 2, 3]
def values = ['a', 'b', 'c']
[keys,values].transpose().collectEntries { it }
tim_yates
Very nice. Looking forward to 1.8 even more now.
ataylor