我们发现here是Ruby中一个稳定的sort_by的实现,它适用于一般情况(即我可以提供我自己的比较算法),而在this thread用户tokland描述了一种非常优雅的方式做一个稳定的sort_by:
module Enumerable
def stable_sort_by
sort_by.with_index { |x, idx| [yield(x), idx] }
end
end
将Enumerator对象与 with_index 一起使用的想法非常简单!我想找到一个类似的优雅解决方案来创建一个稳定版本的#sort函数,它给出了一个比较块。它会像这样使用:
sorted_people = people.stable_sort do |person|
person.name
end
答案 0 :(得分:2)
这是一个解决方案(但远非优雅):
module Enumerable
def stable_sort
each_with_index.sort { |(x, i), (y, j)|
r = yield(x, y)
r == 0 ? i <=> j : r
}.map(&:first)
end
end
它生成一个[element, index]
对数组,并通过将每两个元素传递给给定块来对它们进行排序(就像sort
那样)。如果块返回0
,则比较索引,否则返回块的结果。然后,从生成的数组中提取元素。
示例:
arr = [[2, :baz], [1,:foo], [1, :bar]]
arr.sort { |x, y| x[0] <=> y[0] }
#=> [[1, :bar], [1, :foo], [2, :baz]]
arr.stable_sort { |x, y| x[0] <=> y[0] }
#=> [[1, :foo], [1, :bar], [2, :baz]]