2010-06-01 27 views
1

我有一个简短的groovy算法,根据它们的评级来给食物分配排名。这可以在groovy控制台中运行。该代码完美工作,但我想知道是否有更多的Groovy或编写代码的功能方式。如果可能的话,认为能很好地摆脱局部变量previousItemrankGroovy简单的排名算法

def food = [ 
    [name:'Chocolate Brownie',rating:5.5, rank:null], 
    [name:'Fudge', rating:2.1, rank:null], 
    [name:'Pizza',rating:3.4, rank:null], 
    [name:'Icecream', rating:2.1, rank:null], 
    [name:'Cabbage', rating:1.4, rank:null]] 

food.sort { -it.rating } 

def previousItem = food[0] 
def rank = 1 
previousItem.rank = rank 
food.each { item -> 
    if (item.rating == previousItem.rating) { 
    item.rank = previousItem.rank 
    } else { 
    item.rank = rank 
    } 
    previousItem = item 
    rank++ 
} 

assert food[0].rank == 1 
assert food[1].rank == 2 
assert food[2].rank == 3 
assert food[3].rank == 3 // Note same rating = same rank 
assert food[4].rank == 5 // Note, 4 skipped as we have two at rank 3 

建议?

回答

2

这是我的解决方案:

def rank = 1 
def groupedByRating = food.groupBy { -it.rating } 
groupedByRating.sort().each { rating, items -> 
    items.each { it.rank = rank } 
    rank += items.size() 
} 
+0

感谢团队的创意,我是粉丝。不过,我得到一个空指针,我认为这与sort()调用有关。 我通过内联groupBy并注入了初始等级1.删除了局部变量。 food.sort {-it.rating} .groupBy {it.rating} .inject(1){rank,group - > def项目= group.value items.each {it.rank =排名} 排名+ = items.size() } (UGG,怎么你在注释格式化?) – 2010-06-01 20:39:01

+0

似乎NullPointerException异常是一个错误以前的Groovy版本。我可以用Groovy 1.7.0重现它。使用Groovy 1.7.2,代码的工作方式如上所述。 – 2010-06-02 08:14:37

0

我没有尝试它,但也许这可以工作。

food.eachWithIndex { item, i -> 
    if(i>0 && food[i-1].rating == item.rating) 
     item.rank = food[i-1].rank 
    else 
     item.rank = i + 1 
} 
+0

感谢丹尼尔,该指数为基础的方法似乎干净,内联{-it.rating}调用使其符合我的'没有本地defs'的要求。 – 2010-06-01 20:45:37

0

这里的另一个替代方案,不使用“本地DEFS”与常规注射方法:

food.sort { -it.rating }.inject([index: 0]) { map, current -> 
    current.rank = (current.rating == map.lastRating ? map.lastRank : map.index + 1) 
    [ lastRating: current.rating, lastRank: current.rank, index: map.index + 1 ] 
}