Quantcast

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
Filename
sort.lua
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)