我可以将下面的闭包合并为一个,还是以一种更实用,更优雅的方式做到这一点。我也在其他一些地方(用于测试目的)使用了sortMethod。
例如:countAndMap应该采用
["a b c a a c" , "b b c"]
并返回[x1 : [a:3,c:2,b:1] , x2 : [b:2,c:1]]
def countAndMap(List<String> stringList) {
stringList.withIndex().collect { String s, Integer i -> [(num.call(i)): count.call(s)] }
}
Closure count = {sortMethod.call(it.split().countBy {it}) }
Closure sortMethod = { it.sort { x, y -> x.value <=> y.value } }
Closure num = { "x ${it + 1}".toString()}
没有错误,但我想知道是否有可能以更实用的方式进行操作
答案 0 :(得分:0)
我不确定您所说的“更多功能”是什么意思,但是您可以使用折叠操作(在groovy中称为inject):
list = ["a b c a a c" , "b b c"]
def createSortedHistogram(String toCount) {
toCount
.split() // Create list of words
.inject([:]){ acc, word -> acc[word] = 1 + (acc[word] ?: 0);acc} // create histogram
.sort{-it.value} // sort histogram map by value desc
}
def countAndMap(List<String> list) {
list.withIndex().collectEntries{ sublist, i -> ["x ${i+1}": createSortedHistogram(sublist)] }
}
countAndMap(list)
我认为最有趣的部分是inject
方法。
此解决方案使用初始值[:]
以便将地图用作结果。在每次迭代中,inject
操作要么将一个值为1的新条目添加到映射中(如果单词/关键字在映射中不存在),要么增加单词/关键字的值(如果单词/关键字已存在于映射中)。地图。
请参见Collections
GroovyDoc中的inject
定义。
public Object inject(Object initialValue, Closure closure)
-遍历给定的Collection,将初始值与第一项一起传递给2-arg闭包。结果与第二个项目一起传递回(注入)到封闭中。新结果将与第三个项目一起注入到封闭中,依此类推,直到使用完整个集合为止。在功能上也称为foldLeft或reduce。