Skip to content

Commit

Permalink
Initial work on table extensions
Browse files Browse the repository at this point in the history
  • Loading branch information
andrew-d committed Feb 19, 2013
1 parent f3f89d5 commit c32be98
Showing 1 changed file with 202 additions and 0 deletions.
202 changes: 202 additions & 0 deletions src/tablex.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
--- A module that contains many helpful table extensions.
-- @module tablex

-- Our global environment.
local P = {}

-- Import section:
-- We declare everything this package needs from "outside" here.
local type = type
local pairs, ipairs = pairs, ipairs
local table = table
local error = error
local print = print

-- No more external access after this point.
if string.sub(_VERSION, 5) == '5.2' then
_ENV = P
else
setfenv(1, P)
end

-------------------------------------------------------------------------------
-- Performs a shallow-copy of the given table, optionally copying the input
-- table's metatable.
-- @param t The table to copy
-- @param copy_meta Whether or not to copy the input table's metatable.
-- Defaults to false.
-- @return A copy of t.
function copy(t, copy_meta)
local ret = {}
for k, v in pairs(t) do
ret[k] = v
end
if copy_meta then
setmetatable(ret, getmetatable(t))
end
return ret
end


-------------------------------------------------------------------------------
-- Performs a deep copy of the given table, recursively copying all keys and
-- values. Will also update the new table's metatable to the original tables'.
-- @param t The table to copy
-- @return A deep copy of t.
function deepcopy(t)
if type(t) ~= "table" then return t end

local mt = getmetatable(t)
local ret = {}
for k, v in pairs(t) do
if type(v) == "table" then
v = deepcopy(v)
end
ret[k] = v
end

-- Note that we don't set this before we're done copying, as the original
-- metatable might have __index / __newindex metamethods that interfere.
setmetatable(ret, mt)
return ret
end


-- Save old table.sort, in case we patch it.
local _sort = table.sort

-------------------------------------------------------------------------------
-- Sorts a table, and then returns the new table. Useful for chaining. Note
-- that this operation will sort the original table - i.e. it does not return
-- a copy of the table.
-- @param t The table to sort
-- @param func A comparator function
-- @return A sorted version of t
function sort(t, c)
_sort(t, c)
return t
end


-------------------------------------------------------------------------------
-- Returns whether or not the given table is empty (i.e. whether there are any
-- keys in the table with non-nil values).
-- @param t The table to check
-- @return A boolean value indicating whether the table is empty
function isempty(t)
return not next(t)
end


-------------------------------------------------------------------------------
-- Get the size of the table (the number of keys with non-nil values in the
-- table). Note that this is also alised as length() and count().
-- @param t The table to check
-- @return An integer that represents the size of the table
function size(t)
local n = 0
for _ in pairs(t) do
n = n + 1
end
return n
end
length = size
count = size


-------------------------------------------------------------------------------
-- Returns a list of the keys in a table.
-- @param t The table
-- @return The input table, cleared
function keys(t)
local ret = {}
for k, v in pairs(t) do
table.insert(ret, k)
end
return ret
end


-------------------------------------------------------------------------------
-- Returns a list of the values in a table.
-- @param t The table
-- @return A list-like table representing the values found in t
function values(t)
local ret = {}
for k, v in pairs(t) do
table.insert(ret, v)
end
return ret
end


-------------------------------------------------------------------------------
-- Clears the input table.
-- @param t The table to clear
-- @return The original table passed in, which is now empty
function clear(t)
for k in keys(t) do
t[k] = nil
end
return ret
end


-------------------------------------------------------------------------------
-- Copy one table into another, in-place.
-- @param t The table to copy into
-- @param u The table to copy from
-- @return The original table t
function update(t, u)
for k, v in pairs(u) do
t[k] = v
end
return ret
end


-------------------------------------------------------------------------------
-- Generate a table of all numbers in a range.
-- @param start The start index
-- @param fin The number to end at
-- @param step The step size, which can be negative (default: 1)
-- @return A list-like table of numbers
function range(start, fin, step)
if start == fin then
return {start}
elseif start > fin then
return {}
end

local ret = {}
local counter = 1
step = step or 1

for i = start,fin,step do
ret[counter] = i
counter = counter + 1
end

return ret
end


local patch
local excludes = {
patch,
range,
}
-------------------------------------------------------------------------------
-- Adds all the functions in this module to the 'table' table. Note that we
-- exclude some functions that don't take a table as the first argument, such
-- as this function, the range() function, and so on.
function patch()
for key, val in pairs(P) do
if val ~= patch then
table[key] = val
end
end
end


return P

0 comments on commit c32be98

Please sign in to comment.