Updated sorting to sort numbers within strings more correctly
Kevin Lyles [09-16-12 - 05:50]
Updated sorting to sort numbers within strings more correctly
diff --git a/sort.lua b/sort.lua
index fdc6888..a5ee036 100644
--- a/sort.lua
+++ b/sort.lua
@@ -1,5 +1,69 @@
+local function separateNumericAndTextPortions(str)
+ local result = {}
+ local i, count = 1, 0
+ while i <= str:len() do
+ local j = i
+ if str:sub(i, i) == "-" and i < str:len() then
+ i = i + 1
+ end
+ while i <= str:len() and tonumber(str:sub(i, i)) do
+ i = i + 1
+ end
+ if i > j then
+ local num = tonumber(str:sub(j, i - 1))
+ table.insert(result, num)
+ count = count + 1
+ end
+ j = i
+ while i <= str:len() and not tonumber(str:sub(i, i)) do
+ i = i + 1
+ end
+ if i > j then
+ if str:sub(i - 1, i - 1) == "-" and i <= str:len() then
+ i = i - 1
+ end
+ if i > j then
+ table.insert(result, str:sub(j, i - 1))
+ count = count + 1
+ end
+ end
+ end
+
+ return result
+end
+
+local metatable = {
+ __index = function(tbl, key)
+ tbl[key] = separateNumericAndTextPortions(key)
+ return tbl[key]
+ end
+}
+
+local cache = setmetatable({}, metatable)
+
+local function numericTextSort(str1, str2)
+ local tokens1, tokens2
+ tokens1 = cache[str1]
+ tokens2 = cache[str2]
+
+ local len1, len2 = table.maxn(tokens1), table.maxn(tokens2)
+
+ for i = 1, math.min(len1, len2) do
+ if tokens1[i] < tokens2[i] then
+ return true
+ elseif tokens2[i] < tokens1[i] then
+ return false
+ end
+ end
+
+ return len1 < len2
+end
+
local function mixedSort(e1, e2)
if type(e1) == type(e2) then
+ if type(e1) == "string" then
+ return numericTextSort(e1, e2)
+ end
return e1 < e2
end
return type(e1) < type(e2)