From b0ec33c93887ed2e14b3d1b1be51c1dad073cfe5 Mon Sep 17 00:00:00 2001 From: Kevin Lyles Date: Sun, 16 Sep 2012 00:50:24 -0500 Subject: [PATCH] Updated sorting to sort numbers within strings more correctly --- sort.lua | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) 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) -- 1.7.9.5