尝试按多个参数排序,但在一个参数升序排序和另一个参数降序排序时遇到问题。
array = [20, 10, 40, 1200, 300]
Run Code Online (Sandbox Code Playgroud)
我需要首先按每个数字降序的位数对数组进行排序。
所以我们得到 [1200, 120, 40, 10, 20]
如果长度之间存在联系,我需要按值对它们进行升序排序
所以我们得到: [1200, 120, 10, 20, 40]
我正在尝试使 sort_by 为此工作,但我无法弄清楚如何对第一个参数进行降序排序和第二个参数升序排序。
def digit_sorter(ar)
ar.sort_by {|num| [num.to_s.length, num]}.reverse
end
Run Code Online (Sandbox Code Playgroud)
我也试过 [ [num.to_s.length], [num].reverse ]
# length desc, value asc
def digit_sorter(nums)
nums.sort { |a, b| [b.to_s.length, a] <=> [a.to_s.length, b] }
end
# length asc, value desc
def digit_sorter(nums)
nums.sort { |a, b| [a.to_s.length, b] <=> [b.to_s.length, a] }
end
Run Code Online (Sandbox Code Playgroud)
输入相同的数组[345, 23, 34, 1],输出分别为
# length desc, value asc
[345, 23, 34, 1]
# value desc, length asc
[1, 34, 23, 345]
Run Code Online (Sandbox Code Playgroud)
总是喜欢sort_by在sort时,速度可能是一个问题,sort关键是计算昂贵。
对于升序,只需在此处按原样使用排序键a(数组元素的值)。对于降序,使用-key(减号键),这里-a.to_s.length(数组元素的长度):
array = [20, 10, 40, 1200, 300]
puts array.sort_by { |a| [-a.to_s.length, a] }
Run Code Online (Sandbox Code Playgroud)
印刷:
1200
300
10
20
40
Run Code Online (Sandbox Code Playgroud)
哪个更快:sort_by或sort?
sort_by[是] 当键集很简单时相当昂贵。... 但是,请考虑比较密钥是一项重要操作的情况。一种更有效的技术是sort在sort. Perl 用户经常在 Randal Schwartz 之后称这种方法为 Schwartzian 变换。......这正是sort_by内部所做的。
(来自sort_by文档)
也可以看看
Brandon Dimcheff:“Ruby 的排序与 sort_by”
基准sort_by与sort:
对于 OP 描述的情况,sort_by比 略快sort,尽管两者都很快,因为数组很小(size = 5,见下文)。由于减少了对昂贵的密钥计算的需求,随着数组增长到更现实size=10, 100, 1000,sort_by速度大约是原来的两倍sort。请注意,相对性能在很大程度上取决于数组大小以及sort计算键的成本,因此将其视为单个数据点,不要过度概括这些结果。
代码:
#!/usr/bin/env ruby
require 'benchmark'
max_val = 2_000
[5, 10, 100, 1000].each do |size|
puts "###"
puts "array size=#{size}:"
puts "###"
Benchmark.bmbm do |x|
Kernel.srand(1234)
x.report("sort_by") { 10000.times { (1..size).to_a.map { rand(max_val) } .sort_by { |a| [-a.to_s.length, a] } } }
Kernel.srand(1234)
x.report("sort") { 10000.times { (1..size).to_a.map { rand(max_val) } .sort { |a, b| [b.to_s.length, a] <=> [a.to_s.length, b] } } }
end
end
Run Code Online (Sandbox Code Playgroud)
结果:
###
array size=5:
###
Rehearsal -------------------------------------------
sort_by 0.070000 0.000000 0.070000 ( 0.062603)
sort 0.070000 0.000000 0.070000 ( 0.074214)
---------------------------------- total: 0.140000sec
user system total real
sort_by 0.060000 0.000000 0.060000 ( 0.061337)
sort 0.070000 0.000000 0.070000 ( 0.070706)
###
array size=10:
###
Rehearsal -------------------------------------------
sort_by 0.110000 0.000000 0.110000 ( 0.117958)
sort 0.190000 0.000000 0.190000 ( 0.183992)
---------------------------------- total: 0.300000sec
user system total real
sort_by 0.110000 0.000000 0.110000 ( 0.116410)
sort 0.180000 0.000000 0.180000 ( 0.184045)
###
array size=100:
###
Rehearsal -------------------------------------------
sort_by 1.770000 0.010000 1.780000 ( 1.776254)
sort 3.800000 0.000000 3.800000 ( 3.797437)
---------------------------------- total: 5.580000sec
user system total real
sort_by 1.780000 0.000000 1.780000 ( 1.783407)
sort 3.860000 0.000000 3.860000 ( 3.865884)
###
array size=1000:
###
Rehearsal -------------------------------------------
sort_by 25.380000 0.010000 25.390000 ( 25.403899)
sort 60.290000 0.040000 60.330000 ( 60.374564)
--------------------------------- total: 85.720000sec
user system total real
sort_by 26.010000 0.060000 26.070000 ( 26.122175)
sort 60.990000 0.060000 61.050000 ( 61.134355)
Run Code Online (Sandbox Code Playgroud)