initial release
This commit is contained in:
80
cosmic rage/lua/alphanum.lua
Normal file
80
cosmic rage/lua/alphanum.lua
Normal file
@@ -0,0 +1,80 @@
|
||||
-- alphanum.lua
|
||||
--
|
||||
-- Adapted somewhat from: http://www.davekoelle.com/files/alphanum.lua
|
||||
-- Also see: http://www.davekoelle.com/alphanum.html
|
||||
--
|
||||
-- Implements a sort function that does a more "human readable" sort order.
|
||||
-- It breaks the sort strings into "chunks" and then compares each one naturally,
|
||||
-- depending on whether it is a string or a number (eg. z9.doc compares less than z20.doc)
|
||||
-- It also does a case-insensitive compare (so "nick" and "Nick" come out together).
|
||||
|
||||
-- See also: http://www.gammon.com.au/forum/?id=8698
|
||||
|
||||
--[[
|
||||
Example:
|
||||
|
||||
require "alphanum"
|
||||
|
||||
t={
|
||||
"z18.doc","z19.doc","z2.doc","z16.doc","z17.doc",
|
||||
"z1.doc","z101.doc","z102.doc","z11.doc","z12.doc",
|
||||
"z13.doc","z14.doc","z15.doc","z20.doc","z3.doc",
|
||||
"z4.doc","z5.doc","z6.doc","z10.doc","z100.doc",
|
||||
"z7.doc","z8.doc","z9.doc", "Z9A.doc",
|
||||
}
|
||||
|
||||
table.sort(t, alphanum (t))
|
||||
|
||||
for i=1, #t do
|
||||
print(t[i])
|
||||
end
|
||||
|
||||
--]]
|
||||
|
||||
function alphanum (t)
|
||||
assert (type (t) == "table", "Must pass table to be sorted to alphanum")
|
||||
|
||||
local function chunkString(str)
|
||||
local c = {}
|
||||
for a, b in tostring (str):gmatch("(%d*)(%D*)") do
|
||||
if a ~= "" then c[#c+1] = tonumber(a) end
|
||||
if b ~= "" then c[#c+1] = b end
|
||||
end
|
||||
return c
|
||||
end
|
||||
|
||||
local chunks = {}
|
||||
-- build temporary table of the keys
|
||||
for i=1, #t do
|
||||
chunks [t [i]] = chunkString (t [i])
|
||||
end
|
||||
|
||||
return function (a, b) -- return our sort comparison function
|
||||
|
||||
-- lookup chunked information from previously-built table
|
||||
local achunks = chunks [a]
|
||||
local bchunks = chunks [b]
|
||||
|
||||
for i = 1, math.min (#achunks, #bchunks) do
|
||||
local as, bs = achunks [i], bchunks [i]
|
||||
|
||||
-- if one is a string, make them both strings
|
||||
if type (as) == "string" or type (bs) == "string" then
|
||||
as = (tostring (as)):upper ()
|
||||
bs = (tostring (bs)):upper ()
|
||||
end -- at least one is a string
|
||||
|
||||
-- if they are equal, move onto the next chunk
|
||||
if as ~= bs then
|
||||
return as < bs
|
||||
end -- if
|
||||
end -- for each chunk
|
||||
|
||||
-- still equal? the one with fewer chunks compares less
|
||||
return #achunks < #bchunks
|
||||
|
||||
end -- sort function
|
||||
|
||||
end -- alphanum
|
||||
|
||||
return alphanum
|
||||
Reference in New Issue
Block a user