shortcut for creating a Map from a List in groovy?

2019-01-30 09:26发布

I'd like some sorthand for this:

Map rowToMap(row) {
    def rowMap = [:];
    row.columns.each{ rowMap[it.name] = it.val }
    return rowMap;
}

given the way the GDK stuff is, I'd expect to be able to do something like:

Map rowToMap(row) {
    row.columns.collectMap{ [it.name,it.val] }
}

but I haven't seen anything in the docs... am I missing something? or am I just way too lazy?

8条回答
混吃等死
2楼-- · 2019-01-30 10:19

If what you need is a simple key-value pair, then the method collectEntries should suffice. For example

def names = ['Foo', 'Bar']
def firstAlphabetVsName = names.collectEntries {[it.charAt(0), it]} // [F:Foo, B:Bar]

But if you want a structure similar to a Multimap, in which there are multiple values per key, then you'd want to use the groupBy method

def names = ['Foo', 'Bar', 'Fooey']
def firstAlphabetVsNames = names.groupBy { it.charAt(0) } // [F:[Foo, Fooey], B:[Bar]]
查看更多
戒情不戒烟
3楼-- · 2019-01-30 10:28

ok... I've played with this a little more and I think this is a pretty cool method...

def collectMap = {Closure callback->
    def map = [:]
    delegate.each {
        def r = callback.call(it)
        map[r[0]] = r[1]
    }
    return map
}
ExpandoMetaClass.enableGlobally()
Collection.metaClass.collectMap = collectMap
Map.metaClass.collectMap = collectMap

now any subclass of Map or Collection have this method...

here I use it to reverse the key/value in a Map

[1:2, 3:4].collectMap{[it.value, it.key]} == [2:1, 4:3]

and here I use it to create a map from a list

[1,2].collectMap{[it,it]} == [1:1, 2:2]

now I just pop this into a class that gets called as my app is starting and this method is available throughout my code.

EDIT:

to add the method to all arrays...

Object[].metaClass.collectMap = collectMap
查看更多
登录 后发表回答