Version sort (with alphas, betas, etc.) in ruby
Ruby ships with the Gem class, which knows about versions:
ar = ['10.0.0b12', '10.0.0b3', '10.0.0a2', '9.0.10', '9.0.3']
p ar.sort_by { |v| Gem::Version.new(v) }
# => ["9.0.3", "9.0.10", "10.0.0a2", "10.0.0b3", "10.0.0b12"]
How to sort an alphanumeric array in ruby
You can pass a block to the sort function to custom sort it. In your case you will have a problem because your numbers aren't zero padded, so this method zero pads the numerical parts, then sorts them, resulting in your desired sort order.
a.sort { |a,b|
ap = a.split('_')
a = ap[0] + "%05d" % ap[1] + "%05d" % ap[2]
bp = b.split('_')
b = bp[0] + "%05d" % bp[1] + "%05d" % bp[2]
b <=> a
}
How can I sort an array of strings with numbers like 2.1.2.5?
arr.sort_by{|a| a.split('.').map &:to_i }
Which will:
split
each of the strings into components.- Change each of them into integers (
map &:to_i
). - Compare between each other these arrays.
How to do version numbers?
[major].[minor].[release].[build]
major: Really a marketing decision. Are you ready to call the version 1.0? Does the company consider this a major version for which customers might have to pay more, or is it an update of the current major version which may be free? Less of an R&D decision and more a product decision.
minor: Starts from 0 whenever major is incremented. +1 for every version that goes public.
release: Every time you hit a development milestone and release the product, even internally (e.g. to QA), increment this. This is especially important for communication between teams in the organization. Needless to say, never release the same 'release' twice (even internally). Reset to 0 upon minor++ or major++.
build: Can be a SVN revision, I find that works best.
Examples
My current chrome: 83.0.4103.61
Making my own sort method in Ruby
Here are a few observations about your code:
- since
test_obj
is a string,'#{tested_obj}'
is the same as#{tested_obj}
, which is the same astested_obj
. - declaring
sorted_array = []
has no effect. Being a local variable, it is not within the scope of teh methodrecursive_sort
. That method receives an array that it callssorted_array
, so you would not want it initialized anyway. - you don't need to create the new array,
still_unsorted
; simply transfer elements fromunsorted_array
tosorted_array
.
Below I've fixed and tightened up your code.
def recursive_sort(unsorted_array, sorted_array = [])
return sorted_array unless unsorted_array.length > 0
smallest = unsorted_array.min
unsorted_array.each {|e| sorted_array << e if e == smallest}
unsorted_array.delete(smallest)
recursive_sort(unsorted_array, sorted_array)
end
unsorted_array = ['gamma', 'alpha', 'delta', 'beta', 'gamma', 'alpha', 'zeta']
p recursive_sort unsorted_array
# => ["alpha", "alpha", "beta", "delta", "gamma", "gamma", "zeta"]
Here's what's happening:
- by giving the second argument of recursive_sort (
sorted_value
) a default value of[]
(an empty array), there is no need for the methodsort
you had previously. sorted_array
is returned if sorting is finished (same asreturn sorted_array if unsorted_array.length == 0
).- use
Enumerable#min
to find the smallest value of the unsorted items (smallest
). - add each instance of
smallest
inunsorted_array
tosorted_array
. - delete all instances of
smallest
inunsorted_array
. - call the same method again, to remove the next smallest unsorted item, etc.
Note
unsorted_array.each {|e| sorted_array << e if e == smallest}
could be expressed in many different ways. Here's one:
sorted_array += [smallest]*(unsorted_array.count {|e| e == smallest})
To see how this works, suppose smallest = 'alpha'
. Then
unsorted_array.count {|e| e == 'alpha'} # => 2
so the above expression is:
sorted_array += ['alpha']*2
which is
sorted_array += ['alpha', 'alpha']
which adds two "alpha"
's to sorted_array
.
Related Topics
Splitting String into Pair of Characters in Ruby
How to Parse a Url and Extract the Required Substring
How to Send an Http Put Request in Ruby
Convert a String of 0-F into a Byte Array in Ruby
How to Stringize/Serialize Ruby Code
How to Memoize a Method That May Return True, False, or Nil in Ruby
Error Installing SQLite3 Gem via Bundler
Ruby on Linux Pty Goes Away Without Eof, Raises Errno::Eio
"Msvcrt-Ruby18.Dll Was Not Found" with Ruby
How to Read Files in an Eventmachine-Based App
What Does ["String"].Pack('H*') Mean
Installing Rmagick Gem -- Can't Find Magickwand.H
Set Locale Automatically in Ruby on Rails
Ruby Converting String Encoding from Iso-8859-1 to Utf-8 Not Working
Rails Custom Validation Based on a Regex
Escaping Apostrophes Using Gsub
What Are the Ruby Win32API Parameters | How to Pass a Null Pointer