我们找到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 函数的稳定版本,其中给定一个比较 block 。它将像这样使用:
sorted_people = people.stable_sort do |person|
person.name
end
最佳答案
这是一个解决方案(但远非优雅):
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]
对数组,并通过将每两个元素传递给给定 block 来对它们进行排序(就像 sort
所做的那样)。如果 block 返回0
,它会比较索引,否则,它返回 block 的结果。然后,从生成的数组中提取元素。
示例:
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]]
关于ruby - 稳定的 #sort 占用 block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28235104/