From b75ada22d8604a8c4bcfdcae69f489257808d693 Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Tue, 28 Sep 2010 16:09:40 +0200 Subject: [PATCH] gears.sort: Import The difference to table.sort() is that this is guranteed to be stable. Signed-off-by: Uli Schlachter --- lib/gears/init.lua.in | 1 + lib/gears/sort.lua.in | 83 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 lib/gears/sort.lua.in diff --git a/lib/gears/init.lua.in b/lib/gears/init.lua.in index 5920eeaf..4948595d 100644 --- a/lib/gears/init.lua.in +++ b/lib/gears/init.lua.in @@ -5,6 +5,7 @@ --------------------------------------------------------------------------- require("gears.color") +require("gears.sort") module("gears") diff --git a/lib/gears/sort.lua.in b/lib/gears/sort.lua.in new file mode 100644 index 00000000..5b1647b1 --- /dev/null +++ b/lib/gears/sort.lua.in @@ -0,0 +1,83 @@ +--------------------------------------------------------------------------- +-- @author Uli Schlachter +-- @copyright 2010 Uli Schlachter +-- @release @AWESOME_VERSION@ +--------------------------------------------------------------------------- + +local setmetatable = setmetatable +local ipairs = ipairs +local table = table +local error = error + +module("gears.sort") + +local function less_than_comp(a, b) + return a < b +end + +-- Sort a table. This interface should be identical to table.sort(). +-- The difference to table.sort() is that this sort is stable. +-- @param list The table to sort (we do an in-place sort!). +-- @param comp Comparator used for the sorting +function sort(list, comp) + local comp = comp or less_than_comp + + -- A table could contain non-integer keys which we have to ignore. + local num = 0 + for k, v in ipairs(list) do + num = num + 1 + end + + if num <= 1 then + -- Nothing to do + return + end + + -- Sort until everything is sorted :) + local sorted = false + local n = num + while not sorted do + sorted = true + for i = 1, n - 1 do + -- Two equal elements won't be swapped -> we are stable + if comp(list[i+1], list[i]) then + local tmp = list[i] + list[i] = list[i+1] + list[i+1] = tmp + + sorted = false + end + end + -- The last element is now guaranteed to be in the right spot + n = n - 1 + end +end + +function test() + local function test_one(t) + local len = #t + sort(t) + if len ~= #t then + error("Table lost entries during sort!") + end + if len > 1 then + local cur = table.remove(t, 1) + len = len - 1 + while len > 0 do + local next = table.remove(t, 1) + if cur > next then + error("Table not sorted!") + end + cur = next + len = len -1 + end + end + end + test_one({1, 2, 3, 4, 5, 6}) + test_one({6, 5, 4, 3, 2, 1}) + return true +end + +setmetatable(_M, { __call = function (_, ...) return sort(...) end }) + +-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80