Groovy方法如何多次返回?

时间:2015-09-18 12:45:05

标签: groovy

我试图通过以下代码从排序后的地图中获取前K个元素:

//return top rank k elements
public static LinkedHashMap<String,Double> getTopRank(int i){
    //store top k elements
    LinkedHashMap<String, Double> result=new LinkedHashMap<>();
    int count=0;
    //use the static rankMap in the class
    rankMap.each {key,value->
        result.put(key, value);
        count++;
        if(count>=i){
            println "Time to return"
            return result;
        }
    }
    //in case the loop does not work
    return result;
}

我期望的是,当结果Map已经有i个元素的大小时,该方法将返回,给我一个i-size排序的地图。请注意rankMap以我想要的特定顺序存储元素,并且它的大小远远大于传递给方法的int。 我正在通过

调用方法
LinkedHashMap<String,Double> content=getTopRank(outputSize);

但出乎意料的是,最终内容的大小为rankMap而不是i!在控制台中,我看到了数百条Time to return行。行return result一次又一次地执行,直到它到达rankMap的末尾。 我非常确定第getTopRank(outputSize)行不在循环中。然后我觉得奇怪的是为什么这个方法可以多次返回而不会结束。是否由我在关闭时放置return语句引起的? 请告诉我或告诉我Groovy中的情况如何。更进一步,我怎样才能从排序后的地图中获得前k个元素呢?

3 个答案:

答案 0 :(得分:4)

你误解了Groovy的关键概念。

在到达结束之前完成each()执行的唯一方法是抛出异常。如果您想有条件地退出循环,请使用标准循环类型,例如forwhile

int count=0
def result = [:]
for( def e in rankMap ){
  count++
  result[ e.key ] = e.value
  if( i <= count ) return result
}

答案 1 :(得分:2)

方法本身没有返回。 each是一个接收闭包的方法。闭包有自己的返回上下文,它与调用它们的方法无关,因此,循环不会被破坏。

我想建议从地图entrySet获取一个范围并收集结果条目:

def getTopRank(int i) {
    rankMap
        .entrySet()
        .toList()[0..<i]
        .collectEntries()
}

rankMap = [
    'Beatles'        : 'The White Album',
    'Pink Floyd'     : 'The Dark Side of the Moon',
    'Rolling Stones' : 'Sticky Fingers',
    'The Doors'      : 'Morrison Hotel',
    'Bob Dylan'      : 'Bob Dylan'
]


assert getTopRank(2) == [
    'Beatles'    : 'The White Album',
    'Pink Floyd' : 'The Dark Side of the Moon']

assert getTopRank(4) == [
    'Beatles'        : 'The White Album',
    'Pink Floyd'     : 'The Dark Side of the Moon',
    'Rolling Stones' : 'Sticky Fingers',
    'The Doors'      : 'Morrison Hotel',]

答案 2 :(得分:0)

public static LinkedHashMap<String,Double> getTopRank(int i){
    rankMap.take(i)
}

http://www.groovy-lang.org/gdk.html
http://docs.groovy-lang.org/latest/html/groovy-jdk/java/util/Map.html#take(int)