I have a list of files with a bunch of attributes. One of the attributes is the file name which is how I would like to sort the list. However, the list goes something like this: filename 1, filename 2, filename 10, filename 20.
The ruby sort_by method produces this:
files = files.sort_by { |file| file.name }
=> [filename 1, filename 10, filename 2, filename 20]
I would like a more human readable list like filename 1, filename 2, filename 10, filename 20
I found the natural_sort gem but it seems to only work like the sort method. I need something where I can specify what to sort the array by.
Any help?
Here's another take on a "natural" sort method:
class String
def naturalized
scan(/[^\d\.]+|[\d\.]+/).collect { |f| f.match(/\d+(\.\d+)?/) ? f.to_f : f }
end
end
This converts something like "Filename 10"
into a simple array with floats in place of numbers [ "Filename", 10.0 ]
You can use this on your list:
files.sort_by! { |file| file.name.to_s.naturalized }
This has the advantage of working on arbitrary numbers in unpredictable positions. The paranoid .to_s
call in that block is to ensure that there is a string and not an inadvertent nil
when sorting.
generic answer for strings natural sort
array.sort_by {|e| e.split(/(\d+)/).map {|a| a =~ /\d+/ ? a.to_i : a }}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With