arr = [1,3,2,4]
arr.sort #=> [1,2,3,4]
我想要一个数组[0, 2, 1, 3]
(arr.sort
顺序中的原始索引)
使用Ruby 1.9.3有一种简单的方法吗?
谢谢
答案 0 :(得分:17)
xs = [1, 3, 2, 4]
original_indexes = xs.map.with_index.sort.map(&:last)
#=> [0, 2, 1, 3]
答案 1 :(得分:1)
arr=[1,3,2,4]
p arr.map{|e| arr.sort.index(e)}
为避免每次排序,更好的是:
arr=[1,3,2,4]
arr_s = arr.sort
p arr.map{|e| arr_s.index(e)}
已更新
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
得到了结果:
0.281736
0.504314
答案 2 :(得分:0)
我测试了MRI Ruby 2.2.1p85(在Mac和CentOS上),tokland的解决方案返回错误的结果:
xs = [8,3,2,7,5]
xs.map.with_index.sort.map(&:last)
#=> [2, 1, 4, 3, 0] # wrong
Yevgeniy Anfilofyev解决方案有效但不支持非唯一数组:
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]
我提出来了:
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]
答案 3 :(得分:0)
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
此解决方案适用于O(nlogn)
答案 4 :(得分:0)
(0..arr.size - 1).sort_by { |i| arr[i] }
答案 5 :(得分:0)
一种方法是创建一个与原始数组长度相同的临时数组,其中每个元素都是一对:原始数组的值及其索引。
例如对于 [1, 3, 2, 4] 它将是 [[1, 0], [3, 1], [2, 2], [4, 3]]
然后按元素[0]对这个数组进行排序,然后提取元素[1]作为结果。
像这样:
def sort_indices(x)
t = []
i = -1
x.map { |e| t << [e, i += 1] }
t.sort { |a, b| a[0] <=> b[0] }.map{ |a| a[1] }
end
arr = [ 1, 3, 2, 4]
sort_indices(arr)
=> [0, 2, 1, 3]
通过将其作为方法添加到 Array 类,它可以直接在任何数组上调用:
class Array
def sort_indices
t = []
i = -1
self.map { |e| t << [e, i += 1] }
t.sort { |a, b| a[0] <=> b[0] }.map{ |a| a[1] }
end
end
p [40, 10, 50, 62, 27].sort_indices
=>
[1, 4, 0, 2, 3]