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

瓦塞姆

我有一系列哈希:

[
  { :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 /斌/红宝石

需要的'基准'

进制= [] 
1000.times {
  进制<< {:巴=>兰特(1000)} 
} 

N = 500 
Benchmark.bm(20)做| X | 
  x.report(“ sort”){n。次{ary.sort {| a,b | b [:bar] <=> a [:bar]}}} 
  x.report(“反向排序”){n.times {ary.sort {| a,b | a [:bar] <=> b [:bar]} .reverse}} 
  x.report(“ sort_by -a [:bar]”){n。次{ary.sort_by {| a | -a [:bar]}}} 
  x.report(“ sort_by a [:bar] *-1”){n。次{ary.sort_by {| a | a [:bar] *-1}}} 
  x.report(“ sort_by.reverse!”){n。次{ary.sort_by {| a | 一间酒吧] }。

sort 3.960000 0.010000 3.970000(3.990886)
反向排序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)

我认为@Pablosort_by{...}.reverse!最快是有趣的在运行测试之前,我认为它会比“ -a[:bar]慢一些,但取而代之的是,花费比在一次通过中反转整个阵列所需的时间更长的时间。差别不大,但是每提速都会有所帮助。


请注意,这些结果在Ruby 1.9中有所不同

以下是Ruby 1.9.3p194(2012-04-20修订版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上。较新或较快的计算机将具有较低的值,但相对差异将保留。


这是较新的硬件和Ruby 2.1.1版本的更新版本:

#!/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)

...反向方法实际上并不返回反向数组-它返回的枚举数仅从末尾开始并向后工作。

来源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;
}

do *p2-- = *p1++; while (--len > 0); 如果我没记错我的C语言,则会以相反的顺序将指针复制到元素,因此数组是反向的。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何在MapReduce中按降序对数据进行排序?

如何在iOS的降序排列中对数组进行排序?

如何在Scala中按数字对中的第二对按降序对数字对列表进行排序?

如何在Ruby中按多个属性对数组进行排序?

如果JS中存在值,如何根据日期按降序对数组进行排序?

如何找到在JavaScript中按降序对数字数组进行排序所需的最小交换次数

如何在JavaScript中按日期对数组进行排序?

如何在Javascript中按属性对数组进行排序

如何在表中按升序和降序对数据进行排序

如何在Reactjs中按升序或降序对数据进行排序?

如何在Ruby中对数组进行排序

如何在 Ruby 中对数组进行排序

如何在php中按键对数组降序排序?

如何在 Swift 中按倒序/降序按长度对字符串数组进行排序?

按降序对数组进行排序,并在新数组中收集主数组的变化

如何让我的快速排序算法按升序和降序对数组进行排序?

如何在Bash中按降序对字符串数组进行排序?

如何按数组中数组的值对数组进行排序

在Ruby中按批次对数组进行排序

如何在 SQLAlchemy 中按降序对结果进行排序?

如何在Rust中按降序对Vector进行排序?

numpy-如何按降序对值/键对数组进行排序

如何在C中按降序对结构数组排序

在javascript中按降序对数组进行排序,而无需使用任何内置方法

在 o(n) 中按频率降序对数组进行排序且不重复

如何在MongoDB中按数组内容对数组进行排序

如何按降序对数据表框架进行排序

如何按降序对数据框进行排序

如何在R中按列按降序对数据排序