Sorting Numeric Strings in Ruby

Sort Ruby String Array by the number in the string

The below would sort by the number in each string and not the string itself

array.sort_by { |x| x[/\d+/].to_i }
=> ["STRING: 1", "STRING: 2", "STRING: 3", "STRING: 4", "STRING: 5"]

descending order:

array.sort_by { |x| -(x[/\d+/].to_i) }
=> ["STRING: 5", "STRING: 4", "STRING: 3", "STRING: 2", "STRING: 1"]

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)

Sort strings and numbers in Ruby

A general trick for solving tricky sorts is to use #sort_by, with the block returning an array having the primary and secondary sort order (and, if you need it, tertiary, etc.)

a = ['foo', 'bar', '1', '2', '10']  
b = a.sort_by do |s|
if s =~ /^\d+$/
[2, $&.to_i]
else
[1, s]
end
end
p b # => ["bar", "foo", "1", "2", "10"]

This works because of the way array comparison is defined by Ruby. The comparison is defined by the Array#<=> method:

Arrays are compared in an “element-wise” manner; the first element of ary is compared with the first one of other_ary using the <=> operator, then each of the second elements, etc… As soon as the result of any such comparison is non zero (i.e. the two corresponding elements are not equal), that result is returned for the whole array comparison.

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"]

Sorting numeric strings in Ruby

versions = [ "1.0.4", "1.0.6", "1.0.11", "1.1.9", "1.1.10", "1.0.16" ]
sorted = versions.sort_by {|s| s.split('.').map(&:to_i) }
sorted # => ["1.0.4", "1.0.6", "1.0.11", "1.0.16", "1.1.9", "1.1.10"]

What this does is it splits strings into components and compares them numerically.

How to sort numbers in Ruby

You're pushing to your array what sort_no stores, that's your "whole" string "7 3 1 5 11", which can't be sorted that way.

As the array contains just one value, then it does a sort, in its way.

You could split each number and this way you get an array with each number, and then sort them:

gets.chomp.split.map(&:to_i).sort # [1, 3, 5, 7, 11]

This just gets the input, split it on each whitespace, map each value to an integer object, and then you're able to sort it.

Notice is also possible to sort the input introduced after spliting it without mapping the values, in case you want to keep the values as strings:

gets.chomp.split.sort_by(&:to_i) # ["1", "3", "5", "7", "11"]

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)

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.

Sort an Array Mixed With Integers and Strings - Ruby

This will give you the result:

i_want_dogs.sort_by {|x| x.to_s }

UPDATE:

Thanks @vacawama who points out that it will sort numbers alphabetically. If you need to sort number by it's value, other answers will be something you need to try.

Sorting numeric-strings in Rails

You really really don't want to do this sorting in ruby, as you'll lose the ability to chain scopes, paginate results, use limit correctly, etc.

This is specific to Postgres, but should do exactly what you want.

default_scope order("string_to_array(num, '.', '')::int[]")

SQL Fiddle

Postgres docs



Related Topics



Leave a reply



Submit