root/HTTP/NaturalComparator.lua

Revision 1368 (checked in by rsz, 6 months ago)

cleanup

Line 
1 --------------------------------------------------------------------------------
2 -- Title:               NaturalComparator.lua
3 -- Description:         Like a square peg in a round hole
4 -- Author:              Raphaël Szwarc http://alt.textdrive.com/lua/
5 -- Creation Date:       January 30, 2007
6 -- Legal:               Copyright (C) 2007 Raphaël Szwarc
7 --                      Under the terms of the MIT License
8 --                      http://www.opensource.org/licenses/mit-license.html
9 --------------------------------------------------------------------------------
10
11 -- Based on Andre Bogus implementation of David Koelle's Alphanum algorithm:
12 -- http://www.davekoelle.com/files/alphanum.lua
13 -- http://www.davekoelle.com/alphanum.html
14
15 -- import dependencies
16 local math = require( 'math' )
17
18 local getmetatable = getmetatable
19 local setmetatable = setmetatable
20 local tonumber = tonumber
21 local tostring = tostring
22 local type = type
23
24 --------------------------------------------------------------------------------
25 -- NaturalComparator
26 --------------------------------------------------------------------------------
27
28 module( 'NaturalComparator' )
29 _VERSION = '1.0'
30
31 local self = setmetatable( _M, {} )
32 local meta = getmetatable( self )
33
34 --------------------------------------------------------------------------------
35 -- Utilities
36 --------------------------------------------------------------------------------
37
38 local function Token( aString )
39     local aList = {}
40    
41     for aNumber, aString in aString:gmatch( '(%d*)(%D*)' ) do
42         if aNumber:len() > 0 then
43             aList[ #aList + 1 ] = tonumber( aNumber )
44         end
45        
46         if aString:len() > 0 then
47             aList[ #aList + 1 ] = aString
48         end
49     end
50    
51     return aList
52 end
53
54 local function Compare( aString, anotherString )
55     local aToken = Token( tostring( aString or '' ) )
56     local anotherToken = Token( tostring( anotherString or '' ) )
57    
58     for anIndex = 1, math.min( #aToken, #anotherToken ) do
59         local aValue = aToken[ anIndex ]
60         local anotherValue = anotherToken[ anIndex ]
61        
62         if type( aValue ) == 'string' then
63             anotherValue = tostring( anotherValue )
64         elseif type( anotherValue ) == 'string' then
65             aValue = tostring( aValue )
66         end
67        
68         if aValue ~= anotherValue then
69             return aValue < anotherValue
70         end
71     end
72    
73     return #aToken < #anotherToken
74 end
75
76 --------------------------------------------------------------------------------
77 -- Metamethods
78 --------------------------------------------------------------------------------
79
80 function meta:__call()
81     return Compare
82 end
83
84 function meta:__concat( aValue )
85     return tostring( self ) .. tostring( aValue )
86 end
87
88 function meta:__tostring()
89     return ( '%s/%s' ):format( self._NAME, self._VERSION )
90 end
Note: See TracBrowser for help on using the browser.