根据最高的排序字符串

时间:2019-08-09 00:58:22

标签: groovy

我可以将下面的闭包合并为一个,还是以一种更实用,更优雅的方式做到这一点。我也在其他一些地方(用于测试目的)使用了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()}

没有错误,但我想知道是否有可能以更实用的方式进行操作

1 个答案:

答案 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。