将排序的Ruby数组转换为具有可能重复的排名

aar*_*rkk 7 ruby arrays

我在Ruby中有以下数字数组(越高越好),我想对它们进行排名.换句话说,我想转换以下排序列表:

[89 52 52 36 18 18 5]
Run Code Online (Sandbox Code Playgroud)

到以下职级:

[1 2 2 4 5 5 7]
Run Code Online (Sandbox Code Playgroud)

例如,获胜者获得第一名,第二名获得并列,依此类推.显然,重要的一点是,关系是可能的,那些关系必须跳过相应的级别.任何数量的关系都是可能的(3人分享第二名).

有没有一种优雅的方式来执行这种操作?

fal*_*tru 11

使用Enumerable#group_by:

a = [89, 52, 52, 36, 18, 18, 5]

rank = 1
a.group_by {|x| x}.map { |k,v|
  ret = [rank] * v.size
  rank += v.size
  ret
}.flatten
# => [1, 2, 2, 4, 5, 5, 7]
Run Code Online (Sandbox Code Playgroud)

UPDATE

rank, i = 1, 0
a.map { |x|
  i += 1
  x != a[i-2] ? rank = i : rank
}
# => [1, 2, 2, 4, 5, 5, 7]
Run Code Online (Sandbox Code Playgroud)


sim*_*ier 6

使用Enumerable#each_with_index以避免通过数组的每个迭代去:

a = [89, 52, 52, 36, 18, 18, 5]
rank = 1
a.each_with_index.map{|value, i| a[i-1] == value ? rank : rank = i+1}
Run Code Online (Sandbox Code Playgroud)

编辑:我想我也应该测试我的,这里是结果

Calculating -------------------------------------
            falsetru       344 i/100ms
                sawa       436 i/100ms
              Jordan      1174 i/100ms
              Iceman        46 i/100ms
        simongarnier       710 i/100ms
-------------------------------------------------
            falsetru     3411.0 (±3.7%) i/s -      17200 in   5.049500s
                sawa     4437.4 (±3.4%) i/s -      22236 in   5.017073s
              Jordan    11746.5 (±2.3%) i/s -      59874 in   5.099797s
              Iceman      463.4 (±2.4%) i/s -       2346 in   5.065717s
        simongarnier     7442.1 (±3.2%) i/s -      37630 in   5.061725s
Run Code Online (Sandbox Code Playgroud)

不是最好的,但还是打得很好!


Eye*_*dic 5

a = [89, 52, 52, 36, 18, 18, 5]
a.map{ |e| a.index(e) + 1 }
# => [1, 2, 2, 4, 5, 5, 7]
Run Code Online (Sandbox Code Playgroud)

编辑:

来自@Jordan gist的基准(https://gist.github.com/jrunning/488de3a19428b9ebb488)

Calculating -------------------------------------
            falsetru       419 i/100ms
                sawa       514 i/100ms
              Jordan      1438 i/100ms
              Iceman        57 i/100ms
-------------------------------------------------
            falsetru     4232.8 (±2.5%) i/s -      21369 in   5.051639s
                sawa     5032.0 (±3.5%) i/s -      25186 in   5.011681s
              Jordan    15057.5 (±2.7%) i/s -      76214 in   5.065319s
              Iceman      575.7 (±1.9%) i/s -       2907 in   5.051481s
Run Code Online (Sandbox Code Playgroud)