루비에서 내림차순으로 배열 정렬
다음과 같은 해시 배열이 있습니다.
[
{ :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 / ruby '벤치 마크'가 필요합니다 ary = [] 1000. 회 { ary << {: bar => rand (1000)} } n = 500 Benchmark.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 | -술집] } } } 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}} 종료 사용자 시스템 총 실제 정렬 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)
@ Pablo 's sort_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)
내림차순의 의도를 나타내는 빠른 것입니다.
descending = -1
a.sort_by { |h| h[:bar] * descending }
(그동안 더 나은 방법을 생각할 것입니다);)
a.sort_by { |h| h[:bar] }.reverse!
당신은 할 수 있습니다 :
a.sort{|a,b| b[:bar] <=> a[:bar]}
는 어때:
a.sort {|x,y| y[:bar]<=>x[:bar]}
효과가있다!!
irb
>> a = [
?> { :foo => 'foo', :bar => 2 },
?> { :foo => 'foo', :bar => 3 },
?> { :foo => 'foo', :bar => 5 },
?> ]
=> [{:bar=>2, :foo=>"foo"}, {:bar=>3, :foo=>"foo"}, {:bar=>5, :foo=>"foo"}]
>> a.sort {|x,y| y[:bar]<=>x[:bar]}
=> [{:bar=>5, :foo=>"foo"}, {:bar=>3, :foo=>"foo"}, {:bar=>2, :foo=>"foo"}]
우리는 기본적으로 두 가지 옵션이 있습니다 (다른 것들 외에도).
a.sort_by { |h| -h[:bar] }
과
a.sort_by { |h| h[:bar] }.reverse
정렬 키가 고유 한 경우 두 가지 방법으로 동일한 결과를 얻을 수 있지만 그 reverse
방법 은 동일한 키의 순서를 반대로합니다 .
예:
a = [{foo: 1, bar: 1},{foo: 2,bar: 1}]
a.sort_by {|h| -h[:bar]}
=> [{:foo=>1, :bar=>1}, {:foo=>2, :bar=>1}]
a.sort_by {|h| h[:bar]}.reverse
=> [{:foo=>2, :bar=>1}, {:foo=>1, :bar=>1}]
당신은 종종 이것에 대해 신경 쓰지 않아도되지만 때로는 그렇게합니다. 이러한 동작을 피하려면 두 번째 정렬 키를 도입 할 수 있습니다 (적어도 동일한 정렬 키를 가진 모든 항목에 대해 고유해야 함).
a.sort_by {|h| [-h[:bar],-h[:foo]]}
=> [{:foo=>2, :bar=>1}, {:foo=>1, :bar=>1}]
a.sort_by {|h| [h[:bar],h[:foo]]}.reverse
=> [{:foo=>2, :bar=>1}, {:foo=>1, :bar=>1}]
언급 된 벤치 마크 제품군과 관련하여 이러한 결과는 정렬 된 배열에도 적용됩니다. sort_by / 반전 :)
예 :
# foo.rb
require 'benchmark'
NUM_RUNS = 1000
# arr = []
arr1 = 3000.times.map { { num: rand(1000) } }
arr2 = 3000.times.map { |n| { num: n } }.reverse
Benchmark.bm(20) do |x|
{ 'randomized' => arr1,
'sorted' => arr2 }.each do |label, arr|
puts '---------------------------------------------------'
puts label
x.report('sort_by / reverse') {
NUM_RUNS.times { arr.sort_by { |h| h[:num] }.reverse }
}
x.report('sort_by -') {
NUM_RUNS.times { arr.sort_by { |h| -h[:num] } }
}
end
end
그리고 결과 :
$: ruby foo.rb
user system total real
---------------------------------------------------
randomized
sort_by / reverse 1.680000 0.010000 1.690000 ( 1.682051)
sort_by - 1.830000 0.000000 1.830000 ( 1.830359)
---------------------------------------------------
sorted
sort_by / reverse 0.400000 0.000000 0.400000 ( 0.402990)
sort_by - 0.500000 0.000000 0.500000 ( 0.499350)
IPS에서 속도를 측정하려는 사람들에게는;)
require 'benchmark/ips'
ary = []
1000.times {
ary << {:bar => rand(1000)}
}
Benchmark.ips do |x|
x.report("sort") { ary.sort{ |a,b| b[:bar] <=> a[:bar] } }
x.report("sort reverse") { ary.sort{ |a,b| a[:bar] <=> b[:bar] }.reverse }
x.report("sort_by -a[:bar]") { ary.sort_by{ |a| -a[:bar] } }
x.report("sort_by a[:bar]*-1") { ary.sort_by{ |a| a[:bar]*-1 } }
x.report("sort_by.reverse!") { ary.sort_by{ |a| a[:bar] }.reverse }
x.compare!
end
그리고 결과 :
Warming up --------------------------------------
sort 93.000 i/100ms
sort reverse 91.000 i/100ms
sort_by -a[:bar] 382.000 i/100ms
sort_by a[:bar]*-1 398.000 i/100ms
sort_by.reverse! 397.000 i/100ms
Calculating -------------------------------------
sort 938.530 (± 1.8%) i/s - 4.743k in 5.055290s
sort reverse 901.157 (± 6.1%) i/s - 4.550k in 5.075351s
sort_by -a[:bar] 3.814k (± 4.4%) i/s - 19.100k in 5.019260s
sort_by a[:bar]*-1 3.732k (± 4.3%) i/s - 18.706k in 5.021720s
sort_by.reverse! 3.928k (± 3.6%) i/s - 19.850k in 5.060202s
Comparison:
sort_by.reverse!: 3927.8 i/s
sort_by -a[:bar]: 3813.9 i/s - same-ish: difference falls within error
sort_by a[:bar]*-1: 3732.3 i/s - same-ish: difference falls within error
sort: 938.5 i/s - 4.19x slower
sort reverse: 901.2 i/s - 4.36x slower
오름차순에서 내림차순으로 또는 그 반대로 간단한 솔루션은 다음과 같습니다.
STRINGS
str = ['ravi', 'aravind', 'joker', 'poker']
asc_string = str.sort # => ["aravind", "joker", "poker", "ravi"]
asc_string.reverse # => ["ravi", "poker", "joker", "aravind"]
치수
digit = [234,45,1,5,78,45,34,9]
asc_digit = digit.sort # => [1, 5, 9, 34, 45, 45, 78, 234]
asc_digit.reverse # => [234, 78, 45, 45, 34, 9, 5, 1]
참고 URL : https://stackoverflow.com/questions/2642182/sorting-an-array-in-descending-order-in-ruby
'IT' 카테고리의 다른 글
iPhone 시뮬레이터에서 앱이 실행 중인지 프로그래밍 방식으로 확인할 수 있습니까? (0) | 2020.03.30 |
---|---|
선택 상자에서 항목 제거 (0) | 2020.03.30 |
인터넷에 안드로이드 에뮬레이터를 연결하는 방법 (0) | 2020.03.29 |
파일에서 모든 문자열을 PowerShell로 바꾸려면 어떻게해야합니까? (0) | 2020.03.29 |
C # 프로그램을 50msec 동안 절전 모드로 전환하려면 어떻게합니까? (0) | 2020.03.29 |