从groovy中的列表创建地图的快捷方式?
时间:2020-03-05 18:41:14 来源:igfitidea点击:
我想要一些排序方法:
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] } }
但我没有在文档中看到任何内容...我缺少什么吗?还是我太懒了?
解决方案
回答
我找不到任何内置的东西...但是使用ExpandoMetaClass可以做到这一点:
ArrayList.metaClass.collectMap = {Closure callback-> def map = [:] delegate.each { def r = callback.call(it) map[r[0]] = r[1] } return map }
这会将collectMap方法添加到所有ArrayLists中。。我不确定为什么将其添加到List或者Collection中不起作用。
assert ["foo":"oof", "42":"24", "bar":"rab"] == ["foo", "42", "bar"].collectMap { return [it, it.reverse()] }
从列表到带有一个闭包的计算地图...正是我想要的。
编辑:之所以无法将方法添加到列表和集合接口是因为我没有这样做:
List.metaClass.enableGlobally()
在该方法调用之后,我们可以将方法添加到接口..在这种情况下,这意味着我的collectMap方法将在如下范围内工作:
(0..2).collectMap{[it, it*2]}
产生地图:[0:0,1:2,2:4]
回答
另外,如果我们使用的是Google收藏夹(http://code.google.com/p/google-collections/),则可以执行以下操作:
map = Maps.uniqueIndex(list, Functions.identity());
回答
好的...我已经玩了一点,我认为这是一个很酷的方法...
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
现在Map或者Collection的任何子类都具有此方法...
在这里我用它来反转地图中的键/值
[1:2, 3:4].collectMap{[it.value, it.key]} == [2:1, 4:3]
在这里我用它从列表中创建地图
[1,2].collectMap{[it,it]} == [1:1, 2:2]
现在,我将其弹出到一个类中,该类在我的应用程序启动时被调用,并且此方法在我的代码中均可用。
编辑:
将方法添加到所有数组...
Object[].metaClass.collectMap = collectMap
回答
这样的事呢?
// setup class Pair { String k; String v; public Pair(def k, def v) { this.k = k ; this.v = v; } } def list = [ new Pair('a', 'b'), new Pair('c', 'd') ] // the idea def map = [:] list.each{ it -> map.putAt(it.k, it.v) } // verify println map['c']
回答
签出"注入"。真正的函数式编程语言称之为"折叠"。
columns.inject([:]) { memo, entry -> memo[entry.name] = entry.val return memo }
而且,在使用它时,我们可能想将方法定义为Categories而不是在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') }
回答
问这个问题时,groupBy方法不可用吗?