Algorithm Groovy中的简单排序算法

Algorithm Groovy中的简单排序算法,algorithm,groovy,ranking,Algorithm,Groovy,Ranking,我有一个简短的groovy算法,用于根据食物的评级为它们分配排名。这可以在groovy控制台中运行。代码工作得非常完美,但我想知道是否有一种更为Groovy或functional的代码编写方式。认为如果可能的话,最好去掉previousItem和rank局部变量 def food = [ [name:'Chocolate Brownie',rating:5.5, rank:null], [name:'Fudge', rating:2.1, rank:null], [name:'Piz

我有一个简短的groovy算法,用于根据食物的评级为它们分配排名。这可以在groovy控制台中运行。代码工作得非常完美,但我想知道是否有一种更为Groovy或functional的代码编写方式。认为如果可能的话,最好去掉
previousItem
rank
局部变量

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

建议?

我没有尝试过,但也许这可以奏效

food.eachWithIndex { item, i ->
    if( i>0 && food[i-1].rating == item.rating ) 
        item.rank = food[i-1].rank
    else
        item.rank = i + 1
}
这是我的解决方案:

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

下面是另一个不在groovy注入方法中使用“local 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 ]
}

谢谢你的groupBy创意,我是个粉丝。但是我得到了一个空指针,我认为它与sort()调用有关。我通过内联groupBy并注入初始秩1来移除局部变量。food.sort{-it.rating}.groupBy{it.rating}.inject(1){rank,group->def items=group.value items.each{it.rank=rank}rank+=items.size()}(ugg,如何在注释中格式化?)NullPointerException似乎是以前Groovy版本的一个bug。我可以用Groovy 1.7.0复制它。在Groovy 1.7.2中,代码按所述工作。感谢Daniel,基于索引的方法看起来很干净,内联sort{-it.rating}调用使其符合我的“无本地defs”要求。