وحدة:table/empty
المظهر
local table_get_metamethod = "Module:table/getMetamethod"
local next = next
local pairs = pairs
local pairs_default_iter = pairs{}
local function get_metamethod(...)
get_metamethod = require(table_get_metamethod)
return get_metamethod(...)
end
-- Not possible to simply iterate with a for-loop, since removing a key means
-- it can't be given to next() on the subsequent iteration. Instead, repeatedly
-- giving next() the initial state and key will either return some valid key,
-- which can then be removed, or nil, once the table is empty.
local function empty_raw(t, iter, state, init)
while true do
local k = iter(state, init)
if k == nil then
return t
end
t[k] = nil
end
end
--[==[
Given a table, sets all keys to {nil}. If `raw` is set, then metamethods will be ignored.
Warning: this function is only recommended for tables with a small handful of keys, where reusing a table will avoid creating a large number of temporary objects. In the vast majority of situations, it is more efficient to simply create a new table.]==]
return function(t, raw)
if raw then
return empty_raw(t, next, t)
end
-- If `raw` is not set, try to check for a __pairs metamethod. The check
-- will fail if there's a protected metatable, but if it succeeds and
-- there's no __pairs metamethod, use empty_raw() as an optimisation.
local success, __pairs = get_metamethod(t, "__pairs")
if success and __pairs == nil then
return empty_raw(t, next, t)
end
-- If the iterator returned by the __pairs metamethod is just the default
-- pairs iterator or next(), use empty_raw() with the returned state and
-- key. This is most likely to happen if a protected metatable doesn't have
-- a __pairs metamethod.
local iter, state, k = pairs(t)
if iter == pairs_default_iter or iter == next then
return empty_raw(t, iter, state, k)
end
-- If the iterator returns nothing, `t` is already empty.
k = iter(state, k)
if k == nil then
return t -- already empty
end
-- Otherwise, build a table of keys first, then iterate over it to remove
-- keys from `t`, which ensures removals don't disrupt the loop.
local keys = {[k] = true}
for k in iter, state, k do
keys[k] = true
end
for k in next, keys do
t[k] = nil
end
return t
end