Вот несколько способов сделать это.
arr = [7, 5, 35, 8, 12, 17, 47, 47, 37, 64, 22, 55, 13]
Оба начинаются со следующего вычисления
odd, even = arr.each_with_index.partition { |n,i| n.odd? }
#=> [[[7, 0], [5, 1], [35, 2], [17, 5], [47, 6], [47, 7], [37, 8], [55, 11], [13, 12]],
# [[8, 3], [12, 4], [64, 9], [22, 10]]]
odd
#=> [[7, 0], [5, 1], [35, 2], [17, 5], [47, 6], [47, 7], [37, 8], [55, 11], [13, 12]]
even
#=> [[8, 3], [12, 4], [64, 9], [22, 10]]
См. Enumerable # each_with_index , Enumerable # раздел и Целое число # нечетное? .
# 1
odd_val, odd_idx = odd.transpose
#=> [[7, 5, 35, 17, 47, 47, 37, 55, 13],
# [0, 1, 2, 5, 6, 7, 8, 11, 12]]
a = even.concat(odd_val.sort.zip(odd_idx))
#=> [[8, 3], [12, 4], [64, 9], [22, 10], [5, 0], [7, 1], [13, 2],
# [17, 5], [35, 6], [37, 7], [47, 8], [47, 11], [55, 12]]
h = a.map(&:reverse).to_h
#=> {3=>8, 4=>12, 9=>64, 10=>22, 0=>5, 1=>7, 2=>13, 5=>17, 6=>35, 7=>37,
# 8=>47, 11=>47, 12=>55}
h.values_at(*0..arr.size-1)
#=> [5, 7, 13, 8, 12, 17, 35, 37, 47, 64, 22, 47, 55]
Примечание:
odd_val.sort.zip(odd_idx)
#=> [5, 7, 13, 17, 35, 37, 47, 47, 55].zip([0, 1, 2, 5, 6, 7, 8, 11, 12])
#=> [[5, 0], [7, 1], [13, 2], [17, 5], [35, 6], [37, 7], [47, 8], [47, 11], [55, 12]]
См. Array # sort , Array # zip и Hash # values_at .
# 2
a = odd.map(&:first).sort
#=> [5, 7, 13, 17, 35, 37, 47, 47, 55]
even.each { |n,i| a.insert(i,n) }
a #=> [5, 7, 13, 8, 12, 17, 35, 37, 47, 64, 22, 47, 55]
См. Array # insert .