gpt4 book ai didi

ruby - 如何在 Ruby 中按降序对数组进行排序

转载 作者:数据小太阳 更新时间:2023-10-29 06:16:24 25 4
gpt4 key购买 nike

我有一个哈希数组:

[
{ :foo => 'foo', :bar => 2 },
{ :foo => 'foo', :bar => 3 },
{ :foo => 'foo', :bar => 5 },
]

我试图根据每个散列中 :bar 的值按降序对这个数组进行排序。

我正在使用 sort_by 对以上数组进行排序:

a.sort_by { |h| h[:bar] }

但是,这会按升序对数组进行排序。如何使其按降序排序?

一种解决方案是执行以下操作:

a.sort_by { |h| -h[:bar] }

但是那个负号好像不太合适。

最佳答案

对各种建议的答案进行基准测试总是很有启发性的。这是我发现的:

#!/usr/bin/rubyrequire 'benchmark'ary = []1000.times {   ary << {:bar => rand(1000)} }n = 500Benchmark.bm(20) do |x|  x.report("sort")               { n.times { ary.sort{ |a,b| b[:bar] <=> a[:bar] } } }  x.report("sort reverse")       { n.times { ary.sort{ |a,b| a[:bar] <=> b[:bar] }.reverse } }  x.report("sort_by -a[:bar]")   { n.times { ary.sort_by{ |a| -a[:bar] } } }  x.report("sort_by a[:bar]*-1") { n.times { ary.sort_by{ |a| a[:bar]*-1 } } }  x.report("sort_by.reverse!")   { n.times { ary.sort_by{ |a| a[:bar] }.reverse } }end                          user     system      total        realsort                  3.960000   0.010000   3.970000 (  3.990886)sort reverse          4.040000   0.000000   4.040000 (  4.038849)sort_by -a[:bar]      0.690000   0.000000   0.690000 (  0.692080)sort_by a[:bar]*-1    0.700000   0.000000   0.700000 (  0.699735)sort_by.reverse!      0.650000   0.000000   0.650000 (  0.654447)

I think it's interesting that @Pablo's sort_by{...}.reverse! is fastest. Before running the test I thought it would be slower than "-a[:bar]" but negating the value turns out to take longer than it does to reverse the entire array in one pass. It's not much of a difference, but every little speed-up helps.


Please note that these results are different in Ruby 1.9

Here are results for Ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-darwin10.8.0]:

                           user     system      total        real
sort 1.340000 0.010000 1.350000 ( 1.346331)
sort reverse 1.300000 0.000000 1.300000 ( 1.310446)
sort_by -a[:bar] 0.430000 0.000000 0.430000 ( 0.429606)
sort_by a[:bar]*-1 0.420000 0.000000 0.420000 ( 0.414383)
sort_by.reverse! 0.400000 0.000000 0.400000 ( 0.401275)

这些是在旧的 MacBook Pro 上。更新或更快的机器将具有较低的值,但相对差异将保持不变。


这是在新硬件和 2.1.1 版 Ruby 上的一些更新版本:

#!/usr/bin/ruby

require 'benchmark'

puts "Running Ruby #{RUBY_VERSION}"

ary = []
1000.times {
ary << {:bar => rand(1000)}
}

n = 500

puts "n=#{n}"
Benchmark.bm(20) do |x|
x.report("sort") { n.times { ary.dup.sort{ |a,b| b[:bar] <=> a[:bar] } } }
x.report("sort reverse") { n.times { ary.dup.sort{ |a,b| a[:bar] <=> b[:bar] }.reverse } }
x.report("sort_by -a[:bar]") { n.times { ary.dup.sort_by{ |a| -a[:bar] } } }
x.report("sort_by a[:bar]*-1") { n.times { ary.dup.sort_by{ |a| a[:bar]*-1 } } }
x.report("sort_by.reverse") { n.times { ary.dup.sort_by{ |a| a[:bar] }.reverse } }
x.report("sort_by.reverse!") { n.times { ary.dup.sort_by{ |a| a[:bar] }.reverse! } }
end

# >> Running Ruby 2.1.1
# >> n=500
# >> user system total real
# >> sort 0.670000 0.000000 0.670000 ( 0.667754)
# >> sort reverse 0.650000 0.000000 0.650000 ( 0.655582)
# >> sort_by -a[:bar] 0.260000 0.010000 0.270000 ( 0.255919)
# >> sort_by a[:bar]*-1 0.250000 0.000000 0.250000 ( 0.258924)
# >> sort_by.reverse 0.250000 0.000000 0.250000 ( 0.245179)
# >> sort_by.reverse! 0.240000 0.000000 0.240000 ( 0.242340)

在较新的 Macbook Pro 上使用 Ruby 2.2.1 运行上述代码的新结果。同样,确切的数字并不重要,重要的是它们之间的关系:

Running Ruby 2.2.1
n=500
user system total real
sort 0.650000 0.000000 0.650000 ( 0.653191)
sort reverse 0.650000 0.000000 0.650000 ( 0.648761)
sort_by -a[:bar] 0.240000 0.010000 0.250000 ( 0.245193)
sort_by a[:bar]*-1 0.240000 0.000000 0.240000 ( 0.240541)
sort_by.reverse 0.230000 0.000000 0.230000 ( 0.228571)
sort_by.reverse! 0.230000 0.000000 0.230000 ( 0.230040)

在 2015 年中期的 MacBook Pro 上针对 Ruby 2.7.1 进行了更新:

Running Ruby 2.7.1
n=500
user system total real
sort 0.494707 0.003662 0.498369 ( 0.501064)
sort reverse 0.480181 0.005186 0.485367 ( 0.487972)
sort_by -a[:bar] 0.121521 0.003781 0.125302 ( 0.126557)
sort_by a[:bar]*-1 0.115097 0.003931 0.119028 ( 0.122991)
sort_by.reverse 0.110459 0.003414 0.113873 ( 0.114443)
sort_by.reverse! 0.108997 0.001631 0.110628 ( 0.111532)

...the reverse method doesn't actually return a reversed array - it returns an enumerator that just starts at the end and works backwards.

Array#reverse 的来源是:

               static VALUE
rb_ary_reverse_m(VALUE ary)
{
long len = RARRAY_LEN(ary);
VALUE dup = rb_ary_new2(len);

if (len > 0) {
const VALUE *p1 = RARRAY_CONST_PTR_TRANSIENT(ary);
VALUE *p2 = (VALUE *)RARRAY_CONST_PTR_TRANSIENT(dup) + len - 1;
do *p2-- = *p1++; while (--len > 0);
}
ARY_SET_LEN(dup, RARRAY_LEN(ary));
return dup;
}

做 *p2-- = *p1++; while (--len > 0); 如果我没记错我的 C,则以相反的顺序复制指向元素的指针,所以数组是颠倒的。

关于ruby - 如何在 Ruby 中按降序对数组进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2642182/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com