mirror of
https://github.com/awesomeWM/awesome
synced 2024-11-17 07:47:41 +01:00
4744a744f0
When calling join with e.g. arguments (nil, {"a"}), then everything past the nil was ignored, because the code internally used ipairs() to iterate over the arguments and this stops at the first nil it encounters. Fix this by using select() to iterate over the arguments. This also adds a unit test for this problem. Signed-off-by: Uli Schlachter <psychon@znc.in>
232 lines
5.8 KiB
Lua
232 lines
5.8 KiB
Lua
---------------------------------------------------------------------------
|
|
--- Table module for gears
|
|
--
|
|
-- @module gears.table
|
|
---------------------------------------------------------------------------
|
|
|
|
|
|
local rtable = table
|
|
|
|
local gmath = require("gears.math")
|
|
local gtable = {}
|
|
|
|
--- Join all tables given as parameters.
|
|
-- This will iterate all tables and insert all their keys into a new table.
|
|
-- @class function
|
|
-- @name join
|
|
-- @param args A list of tables to join
|
|
-- @return A new table containing all keys from the arguments.
|
|
function gtable.join(...)
|
|
local ret = {}
|
|
for i = 1, select("#", ...) do
|
|
local t = select(i, ...)
|
|
if t then
|
|
for k, v in pairs(t) do
|
|
if type(k) == "number" then
|
|
rtable.insert(ret, v)
|
|
else
|
|
ret[k] = v
|
|
end
|
|
end
|
|
end
|
|
end
|
|
return ret
|
|
end
|
|
|
|
--- Override elements in the first table by the one in the second.
|
|
--
|
|
-- Note that this method doesn't copy entries found in `__index`.
|
|
-- @class function
|
|
-- @name crush
|
|
-- @tparam table t the table to be overriden
|
|
-- @tparam table set the table used to override members of `t`
|
|
-- @tparam[opt=false] boolean raw Use rawset (avoid the metatable)
|
|
-- @treturn table t (for convenience)
|
|
function gtable.crush(t, set, raw)
|
|
if raw then
|
|
for k, v in pairs(set) do
|
|
rawset(t, k, v)
|
|
end
|
|
else
|
|
for k, v in pairs(set) do
|
|
t[k] = v
|
|
end
|
|
end
|
|
|
|
return t
|
|
end
|
|
|
|
--- Pack all elements with an integer key into a new table
|
|
-- While both lua and luajit implement __len over sparse
|
|
-- table, the standard define it as an implementation
|
|
-- detail.
|
|
--
|
|
-- This function remove any non numeric keys from the value set
|
|
--
|
|
-- @class function
|
|
-- @name from_sparse
|
|
-- @tparam table t A potentially sparse table
|
|
-- @treturn table A packed table with all numeric keys
|
|
function gtable.from_sparse(t)
|
|
local keys= {}
|
|
for k in pairs(t) do
|
|
if type(k) == "number" then
|
|
keys[#keys+1] = k
|
|
end
|
|
end
|
|
|
|
table.sort(keys)
|
|
|
|
local ret = {}
|
|
for _,v in ipairs(keys) do
|
|
ret[#ret+1] = t[v]
|
|
end
|
|
|
|
return ret
|
|
end
|
|
|
|
--- Check if a table has an item and return its key.
|
|
-- @class function
|
|
-- @name hasitem
|
|
-- @param t The table.
|
|
-- @param item The item to look for in values of the table.
|
|
-- @return The key were the item is found, or nil if not found.
|
|
function gtable.hasitem(t, item)
|
|
for k, v in pairs(t) do
|
|
if v == item then
|
|
return k
|
|
end
|
|
end
|
|
end
|
|
|
|
--- Get a sorted table with all integer keys from a table
|
|
-- @class function
|
|
-- @name keys
|
|
-- @param t the table for which the keys to get
|
|
-- @return A table with keys
|
|
function gtable.keys(t)
|
|
local keys = { }
|
|
for k, _ in pairs(t) do
|
|
rtable.insert(keys, k)
|
|
end
|
|
rtable.sort(keys, function (a, b)
|
|
return type(a) == type(b) and a < b or false
|
|
end)
|
|
return keys
|
|
end
|
|
|
|
--- Filter a tables keys for certain content types
|
|
-- @class function
|
|
-- @name keys_filter
|
|
-- @param t The table to retrieve the keys for
|
|
-- @param ... the types to look for
|
|
-- @return A filtered table with keys
|
|
function gtable.keys_filter(t, ...)
|
|
local keys = gtable.keys(t)
|
|
local keys_filtered = { }
|
|
for _, k in pairs(keys) do
|
|
for _, et in pairs({...}) do
|
|
if type(t[k]) == et then
|
|
rtable.insert(keys_filtered, k)
|
|
break
|
|
end
|
|
end
|
|
end
|
|
return keys_filtered
|
|
end
|
|
|
|
--- Reverse a table
|
|
-- @class function
|
|
-- @name reverse
|
|
-- @param t the table to reverse
|
|
-- @return the reversed table
|
|
function gtable.reverse(t)
|
|
local tr = { }
|
|
-- reverse all elements with integer keys
|
|
for _, v in ipairs(t) do
|
|
rtable.insert(tr, 1, v)
|
|
end
|
|
-- add the remaining elements
|
|
for k, v in pairs(t) do
|
|
if type(k) ~= "number" then
|
|
tr[k] = v
|
|
end
|
|
end
|
|
return tr
|
|
end
|
|
|
|
--- Clone a table
|
|
-- @class function
|
|
-- @name clone
|
|
-- @param t the table to clone
|
|
-- @param deep Create a deep clone? (default: true)
|
|
-- @return a clone of t
|
|
function gtable.clone(t, deep)
|
|
deep = deep == nil and true or deep
|
|
local c = { }
|
|
for k, v in pairs(t) do
|
|
if deep and type(v) == "table" then
|
|
c[k] = gtable.clone(v)
|
|
else
|
|
c[k] = v
|
|
end
|
|
end
|
|
return c
|
|
end
|
|
|
|
---
|
|
-- Returns an iterator to cycle through, starting from the first element or the
|
|
-- given index, all elements of a table that match a given criteria.
|
|
--
|
|
-- @class function
|
|
-- @name iterate
|
|
-- @param t the table to iterate
|
|
-- @param filter a function that returns true to indicate a positive match
|
|
-- @param start what index to start iterating from. Default is 1 (=> start of
|
|
-- the table)
|
|
function gtable.iterate(t, filter, start)
|
|
local count = 0
|
|
local index = start or 1
|
|
local length = #t
|
|
|
|
return function ()
|
|
while count < length do
|
|
local item = t[index]
|
|
index = gmath.cycle(#t, index + 1)
|
|
count = count + 1
|
|
if filter(item) then return item end
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
--- Merge items from the one table to another one
|
|
-- @class function
|
|
-- @name merge
|
|
-- @tparam table t the container table
|
|
-- @tparam table set the mixin table
|
|
-- @treturn table Return `t` for convenience
|
|
function gtable.merge(t, set)
|
|
for _, v in ipairs(set) do
|
|
table.insert(t, v)
|
|
end
|
|
return t
|
|
end
|
|
|
|
--- Map a function to a table. The function is applied to each value
|
|
-- on the table, returning a table of the results.
|
|
-- @class function
|
|
-- @name map
|
|
-- @tparam function f the function to be applied to each value on the table
|
|
-- @tparam table tbl the container table whose values will be operated on
|
|
-- @treturn table Return a table of the results
|
|
function gtable.map(f, tbl)
|
|
local t = {}
|
|
for k,v in pairs(tbl) do
|
|
t[k] = f(v)
|
|
end
|
|
return t
|
|
end
|
|
|
|
|
|
return gtable
|