Skip to content

Instantly share code, notes, and snippets.

@Coro365

Coro365/natural_sort.rb

Last active Apr 18, 2020
Embed
What would you like to do?
Rearrange arrays naturally
module Natural_sort
def natural_sort
zero_length = max_num_length_of(self)
number_formated_names = self.map do |data|
name_array = data.scan(/(\D*)(\d+)(\D*)/).flatten.reject(&:empty?)
name_array = [data] if name_array.empty?
number_formated_name_array = name_array.map do |e|
e.match(/\d/) ? format("%0#{zero_length}d", e.to_i) : e
end
number_formated_name_array.join
end
names_hash = Hash[self.zip number_formated_names]
names_hash_sorted = Hash[names_hash.sort_by{ |k,v| v }]
names_hash_sorted.keys
end
def max_num_length_of(names)
max_num_len_of_names = names.map do |name|
if m = name.scan(/\d+/)
m.map { |e| e.length }.sort.last
end
end
max_num_len_of_names.compact.sort.last
end
end
# Example
include Natural_sort
names = ["20191212_report.md",
"alice",
"syamico",
"momo",
"documents.txt",
"doc10ver1",
"doc1ver1",
"doc1ver10",
"doc1ver2",
"doc2ver10",
"doc2ver4",
"10. do.txt",
"1. plan.txt",
"2. do.txt"]
puts "non sort"
pp names
puts "default sort"
pp names.sort
puts "natural sort"
pp names.natural_sort
# ruby natural_sort.rb
#
# non sort
# ["20191212_report.md",
# "alice",
# "syamico",
# "momo",
# "documents.txt",
# "doc10ver1",
# "doc1ver1",
# "doc1ver10",
# "doc1ver2",
# "doc2ver10",
# "doc2ver4",
# "10. do.txt",
# "1. plan.txt",
# "2. do.txt"]
#
# default sort
# ["1. plan.txt",
# "10. do.txt",
# "2. do.txt",
# "20191212_report.md",
# "alice",
# "doc10ver1",
# "doc1ver1",
# "doc1ver10",
# "doc1ver2",
# "doc2ver10",
# "doc2ver4",
# "documents.txt",
# "momo",
# "syamico"]
#
# natural sort
# ["1. plan.txt",
# "2. do.txt",
# "10. do.txt",
# "20191212_report.md",
# "alice",
# "doc1ver1",
# "doc1ver2",
# "doc1ver10",
# "doc2ver4",
# "doc2ver10",
# "doc10ver1",
# "documents.txt",
# "momo",
# "syamico"]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.