Sha256: 87d81813934473a15e5ef2d9df181497ea12419aa8e12313f63aefe0807d62e8
Contents?: true
Size: 1.57 KB
Versions: 4
Compression:
Stored size: 1.57 KB
Contents
module Enumerable def sort_by_alphanum sort do |a, b| if block_given? grouped_compare(yield(a), yield(b)) else grouped_compare(a, b) end end end def sort_by_alphanum! sort! do |a, b| if block_given? grouped_compare(yield(a), yield(b)) else grouped_compare(a, b) end end end private ALL_NUM = /\d+/ ALL_ALPHA = /[A-Za-z]+/ NON_ALPHANUM = /[^A-Za-z0-9]+/ def grouped_compare(a, b) a_scanner = StringScanner.new(a) b_scanner = StringScanner.new(b) # each loop has to do exactly 1 non-nil-scan on both scanners or return a non-zero value. loop do ret = \ if a_scanner.eos? -1 elsif b_scanner.eos? 1 elsif (a_chunk = a_scanner.scan(ALL_NUM)) if (b_chunk = b_scanner.scan(ALL_NUM)) if a_chunk.to_i != b_chunk.to_i a_chunk.to_i <=> b_chunk.to_i else # 03 vs 3 a_chunk <=> b_chunk end elsif b_scanner.scan(ALL_ALPHA) -1 else # NON_ALPHANUM 1 end elsif (a_chunk = a_scanner.scan(ALL_ALPHA)) if (b_chunk = b_scanner.scan(ALL_ALPHA)) a_chunk <=> b_chunk else # ALL_NUM or NON_ALPHANUM 1 end else # NON_ALPHANUM a_chunk = a_scanner.scan(NON_ALPHANUM) if (b_chunk = b_scanner.scan(NON_ALPHANUM)) a_chunk <=> b_chunk else -1 end end return ret if ret != 0 end end end
Version data entries
4 entries across 4 versions & 1 rubygems