originals indexes of sorted elements in Ruby

戏子无情 提交于 2019-12-21 09:29:34

问题


arr = [1,3,2,4]

arr.sort #=> [1,2,3,4]

I would like an array [0, 2, 1, 3] (original indexes in arr.sort order)

Is there a simple way to do that with Ruby 1.9.3?

thank you


回答1:


xs = [1, 3, 2, 4]
original_indexes = xs.map.with_index.sort.map(&:last)
#=> [0, 2, 1, 3]



回答2:


arr=[1,3,2,4]
p arr.map{|e| arr.sort.index(e)}

to avoid sorting each time, better is:

arr=[1,3,2,4]
arr_s = arr.sort
p arr.map{|e| arr_s.index(e)}

UPDATED

arr=[1,3,2,4]
start_time = Time.now
(1..100000).each do |i|
    arr.map{|e| arr.sort.index(e)}
end
elapsed = Time.now - start_time
p elapsed

xs = [1, 3, 2, 4]
start_time = Time.now
(1..100000).each do |i|
    xs.map.with_index.sort.map(&:last)
end
elapsed = Time.now - start_time
p elapsed

and got the result:

0.281736
0.504314



回答3:


I tested on MRI Ruby 2.2.1p85 (on both Mac and CentOS), tokland's solution return a wrong result:

xs = [8,3,2,7,5]
xs.map.with_index.sort.map(&:last)
#=> [2, 1, 4, 3, 0] # wrong

Yevgeniy Anfilofyev solution works but does not support non-unique array:

arr = [8,3,2,7,5]
arr_s = arr.sort
arr.map{|e| arr_s.index(e)}
#=> [4, 1, 0, 3, 2] # correct

arr = [8,3,5,2,8,8,7,5]
arr_s = arr.sort
arr.map{|e| arr_s.index(e)}
#=> [5, 1, 2, 0, 5, 5, 4, 2]

I come up this:

arr = [8,3,5,2,8,8,7,5]
index_order = []
arr.uniq.sort.each do |a|
  index_order += arr.each_index.select{|i| arr[i] == a }
end
r = []
index_order.each_with_index do |a, i|
  r[a] = i
end
r
#=> [5, 1, 2, 0, 6, 7, 4, 3]



回答4:


array = [6, 20, 12, 2, 9, 22, 17]
sorted = array.sort
indices = []
array.each do |n|
  index = (0...sorted.length).bsearch { |x| n <=> sorted[x] }
  indices << index
end
indices

This solution works with O(nlogn)




回答5:


(0..arr.size - 1).sort_by { |i| arr[i] }



来源:https://stackoverflow.com/questions/14446181/originals-indexes-of-sorted-elements-in-ruby

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!