假设我有以下哈希数组:
arr = [{:name=>"foo", :value=>20},
{:name=>"bar", :value=>25},
{:name=>"baz", :value=>30}]
我目前按value
排序,如下:
arr.sort{|a,b| b[:value] <=> a[:value] }
是否可以在排序后将一个元素(即name == 'bar'
)移动到堆栈顶部而不链接另一个方法?理想情况下,这只是排序块中的更多内容。
答案 0 :(得分:2)
快速解决方案(我认为可以重构)
arr.sort{|a,b| a[:name] == 'bar' ? -1 : b[:name] == 'bar' ? 1 : b[:value] <=> a[:value] }
# => [{:name=>"bar", :value=>25}, {:name=>"baz", :value=>30}, {:name=>"foo", :value=>20}]
答案 1 :(得分:1)
首先,您应该使用Schwartzian transform更简洁(效率更高)Enumerable#sort_by:
arr.sort_by { |h| -h[:value]] }
现在,利用数组定义的lexicographical order,可能会写出您要求的内容:
arr.sort_by { |h| [h[:name] == "bar" ? 0 : 1, -h[:value]] }
答案 2 :(得分:0)
arr.sort do |a,b|
if a[:name] == "bar" && b[:name] != "bar"
# a is bar but b is not, put a to the top, i.e. a is smaller than b
-1
elsif a[:name] != "bar" && b[:name] == "bar"
# a is not bar but b is, put b to the top, i.e. a is bigger than b
1
else
# both a and b are "bar", or bot are not "bar", than we can sort them normally
a[:value] <=> b[:value]
end
end
一个肮脏的解决方案,思考如何写得更好......