Sorting an array of strings in Ruby
Both lines do the same (create a new array, which is reverse sorted). The main argument is about readability and performance. array.sort.reverse!
is more readable than array.sort{|x,y| y<=>x}
- I think we can agree here.
For the performance part, I created a quick benchmark script, which gives the following on my system (ruby 1.9.3p392 [x86_64-linux]
):
user system total real
array.sort.reverse 1.330000 0.000000 1.330000 ( 1.334667)
array.sort.reverse! 1.200000 0.000000 1.200000 ( 1.198232)
array.sort!.reverse! 1.200000 0.000000 1.200000 ( 1.199296)
array.sort{|x,y| y<=>x} 5.220000 0.000000 5.220000 ( 5.239487)
Run times are pretty constant for multiple executions of the benchmark script.
array.sort.reverse
(with or without !
) is way faster than array.sort{|x,y| y<=>x}
. Thus, I recommend that.
Here is the script as a Reference:
#!/usr/bin/env ruby
require 'benchmark'
Benchmark.bm do|b|
master = (1..1_000_000).map(&:to_s).shuffle
a = master.dup
b.report("array.sort.reverse ") do
a.sort.reverse
end
a = master.dup
b.report("array.sort.reverse! ") do
a.sort.reverse!
end
a = master.dup
b.report("array.sort!.reverse! ") do
a.sort!.reverse!
end
a = master.dup
b.report("array.sort{|x,y| y<=>x} ") do
a.sort{|x,y| y<=>x}
end
end
Sort array of string with digits and characters in ruby
You're looking for a "natural" sort where the numeric substrings will be compared as numbers as the non-numeric parts will be compared like strings. Conveniently enough, arrays in Ruby compare element-by-element and your format is fairly regular so you can get away with a #sort_by
call and a bit of mangling to convert "12mo-21-classic"
to [12, 'mo-', 21, '-classic']
. Something like this for example:
# This is a bit complicated so we'll give the logic a name.
natural_parts = ->(s) { s.match(/(\d+)(\D+)(\d+)(\D+)/).to_a.drop(1).map.with_index { |e, i| i.even?? e.to_i : e } }
array.sort_by(&natural_parts)
Custom Sort array of strings by another array of strings - Ruby
I assume that:
- every element of
list
is insort_order
; sort_order
may contain elements that are not inlist
;list
may contain duplicates; andsort_order
contains no duplicates.
If sort_order
initially contains duplicates the temporary array sort_order.uniq
can be used in the calculations.
Observe that if, as in the example, list
contains no duplicates and sort_order
contains no elements other than those in list
, sorting list
by the order of its elements in sort_order
is trivial, as it merely returns sort_order
.
The following is more efficient than methods that use sort
or sort_by
(O(n)
versus O(n*log(n)
) computational complexity.)
list = ["gold", "copper", "silver", "copper", "steel", "gold"]
sort_order = ["bronze", "silver", "tin", "gold", "copper", "steel"]
count = list.each_with_object(Hash.new(0)) { |e,h| h[e] += 1 }
#=> {"gold"=>2, "copper"=>2, "silver"=>1, "steel"=>1}
sort_order.flat_map { |e| [e]*count[e] }.reject(&:empty?)
#=> ["silver", "gold", "gold", "copper", "copper", "steel"]
How to sort an array of strings containing numbers and letters in ruby
array.sort_by { |item|
number, letter = *item.split
[letter, number.to_i]
}
Arrays compare as their first element; in case an element is equal, next element is compared.
Efficient way to sort an array of numbers and string in ruby?
One way is to partition
your array by those elements being Integer, to make sure they remain first and then sort the elements of each array:
[4,2,'b',5,'c','a',7].partition { |e| e.is_a?(Integer) }.flat_map(&:sort)
# [2, 4, 5, 7, "a", "b", "c"]
How do I sort a Ruby array of strings by length?
arr = arr.sort_by {|x| x.length}
Or in 1.8.7+:
arr = arr.sort_by(&:length)
Sort an Array of Strings by their Integer Values
I'll throw another method out there since it's the shortest way I can think of
a.sort_by(&:to_i)
Related Topics
How to Completely Remove Webpack and All Its Dependencies from Rails App
How to Do a Before_Action in Ruby (Like in Rails)
What Are Factory_Girl Transient Attributes? Why Would I Use One
How to Get Systemd to Restart Rails App with Puma
Why Is Foreman Gem Ignoring the Port Environment Variable
Using Rest-Client to Download a File to Disk Without Loading It All in Memory First
Why Do I Need Asterisk Before an Array
How to Properly Test Cancan Abilities with Rspec
Can You Create/Write/Append a String to a File in a Single Line in Ruby
How to Profile Rspec with Perftools and Bundler
Best Practice for Limiting the Number of Associations Within a Has_Many Relationship
Rails Include Only Selected Columns from Relation
Single Custom Param Name in Routes for Nested Resources Rails 4.1
How to Return a Fixed Length Binary Representation of an Integer in Ruby
Solid Tutorial for Building a Simple Wiki Application in Ruby on Rails