2016-03-13 45 views
1

我有这样的:红宝石sort_by with_index模

input = ["a","b","c","d","a","b","c","d","a","b","c","d"] 

我想这一点:

result = ["a","a","a","b","b","b","c","c","c","d","d","d"] 

我尝试这样做:

input.sort_by.with_index do |piece, index| 
    index%3 
end 

我得到这个:

["a", "d", "c", "b", "c", "b", "d", "a", "d", "b", "a", "c"] 

为什么?

+2

它应该是'索引%4' –

+0

另一种方法是'input.each_slice(4).to_a.transpose.flatten'。 –

+0

你可以通过'result = index.sort'从'input'得到'result'吗?不知道我明白这个问题... –

回答

2

如果看index % 3,您可以:

input  "a" "b" "c" "d" "a" "b" "c" "d" "a" "b" "c" "d" 
index  0 1 2 3 4 5 6 7 8 9 10 11 
index % 3 0 1 2 0 1 2 0 1 2 0 1 2 

,如果你组他们通过index % 3,您可以:

input  "a" "d" "c" "b" 
index % 3 0 0 0 0 

input  "b" "a" "d" "c" 
index % 3 1 1 1 1 

input  "c" "b" "a" "d" 
index % 3 2 2 2 2 

由于排序在Ruby中并不稳定,当您通过对它们进行排序index % 3,你得到:

[ 
    <some permutation of "a" "d" "c" "b">, 
    <some permutation of "b" "a" "d" "c">, 
    <some permutation of "c" "b" "a" "d">, 
] 

这就是你得到的。

0

试试这个:

input.sort_by.with_index do |piece, index| 
    index%3 + (index.to_f/input.count) 
end 

我们怎么会在这里?

OP的解决方案很接近,但正如@sawa所述,index%3仅给出0,1或2. Ruby的不稳定排序会混淆这些组中的项目。

它不一定是这样。相反,可以对这些排序键进行欺骗,以便ruby别无选择,只需对其进行排序即可。我们只需要一个软糖因素是:

  • 一直增加,但
  • 总是足够小,不会小心碰到我们进入一个新的组(即< 1)

首部曲:在黑暗中

一声枪响考虑,通过index捏造它:

input.sort_by.with_index do |piece, index| 
    index%3 + index 
end 

这可能看起来很愚蠢,但它确实符合1/2标准:总是增加,这只是大。我们可以解决此问题。

情节二:Ruby的救赎

我们知道index < input.count,所以如果我们只是通过input.count分两边我们得到index.to_f/input.count <,这正是我们想要的(但不要忘了转换成浮动) !

input.sort_by.with_index do |piece, index| 
    index%3 + (index.to_f/input.count) 
end 

奖金

我认为这个解决方案是聪明的,但正是由于这个原因,公众实际上并不使用它:

input.sort_by.with_index do |piece, index| 
    index%3 - 1.to_f/(1 + index) 
end