从列表中创建地图的快捷方式?

2022-08-31 09:06:54

我想要一些排序手:

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

鉴于GDK的东西是这样的,我希望能够做这样的事情:

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

但我在文档中没有看到任何东西...我错过了什么吗?还是我只是太懒了?


答案 1

我最近遇到了这样做的需要:将列表转换为地图。这个问题是在Groovy版本1.7.9发布之前发布的,因此collectEntries方法尚不存在。它的工作原理与建议的方法完全相同collectMap

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

如果由于某种原因,您被困在较旧的Groovy版本中,也可以使用注入方法(如这里所建议的那样)。这是一个稍微修改过的版本,在闭包内只接受一个表达式(只是为了保存字符!

Map rowToMap(row) {
    row.columns.inject([:]) {map, col -> map << [(col.name): col.val]}
}

也可以使用运算符代替 .+<<


答案 2

查看“注入”。真正的函数式编程专家称之为“fold”。

columns.inject([:]) { memo, entry ->
    memo[entry.name] = entry.val
    return memo
}

而且,当你使用它时,你可能希望将方法定义为类别,而不是直接在metaClass上。这样,您可以为所有集合定义一次:

class PropertyMapCategory {
    static Map mapProperty(Collection c, String keyParam, String valParam) {
        return c.inject([:]) { memo, entry ->
            memo[entry[keyParam]] = entry[valParam]
            return memo
        }
    }
}

用法示例:

use(PropertyMapCategory) {
    println columns.mapProperty('name', 'val')
}