Add table.foreachi(), phase out ipairs() in API so nil values can be included in lists

This commit is contained in:
Jason Perkins 2013-02-20 09:45:35 -05:00
parent 2e278af5e2
commit 453cae7362
2 changed files with 56 additions and 29 deletions

View File

@ -140,9 +140,9 @@
function recurse(value) function recurse(value)
if type(value) == "table" then if type(value) == "table" then
for _, v in ipairs(value) do table.foreachi(value, function(v)
recurse(v) recurse(v)
end end)
else else
remover(removes, value) remover(removes, value)
end end
@ -182,7 +182,9 @@
if type(field.allowed) == "function" then if type(field.allowed) == "function" then
return field.allowed(value) return field.allowed(value)
else else
for _,v in ipairs(field.allowed) do local n = #field.allowed
for i = 1, n do
local v = field.allowed[i]
if value:lower() == v:lower() then if value:lower() == v:lower() then
return v return v
end end
@ -341,10 +343,10 @@
function api.setfile(target, name, field, value) function api.setfile(target, name, field, value)
if value:find("*") then if value:find("*") then
local values = os.matchfiles(value) local values = os.matchfiles(value)
for _, value in ipairs(values) do table.foreachi(values, function(v)
api.setfile(target, name, field, value) api.setfile(target, name, field, v)
name = name + 1 name = name + 1
end end)
else else
target[name] = path.getabsolute(value) target[name] = path.getabsolute(value)
end end
@ -353,10 +355,10 @@
function api.setdirectory(target, name, field, value) function api.setdirectory(target, name, field, value)
if value:find("*") then if value:find("*") then
local values = os.matchdirs(value) local values = os.matchdirs(value)
for _, value in ipairs(values) do table.foreachi(values, function(v)
api.setdirectory(target, name, field, value) api.setdirectory(target, name, field, values[i])
name = name + 1 name = name + 1
end end)
else else
target[name] = path.getabsolute(value) target[name] = path.getabsolute(value)
end end
@ -411,9 +413,9 @@
local result = {} local result = {}
function recurse(value) function recurse(value)
if type(value) == "table" then if type(value) == "table" then
for _, v in ipairs(value) do table.foreachi(value, function (value)
recurse(v) recurse(value)
end end)
else else
setter(result, #result + 1, field, value) setter(result, #result + 1, field, value)
end end

View File

@ -3,7 +3,7 @@
-- Additions to Lua's built-in table functions. -- Additions to Lua's built-in table functions.
-- Copyright (c) 2002-2008 Jason Perkins and the Premake project -- Copyright (c) 2002-2008 Jason Perkins and the Premake project
-- --
-- --
-- Returns true if the table contains the specified value. -- Returns true if the table contains the specified value.
@ -17,7 +17,7 @@
end end
return false return false
end end
-- --
-- Make a copy of the indexed elements of the table. -- Make a copy of the indexed elements of the table.
@ -39,23 +39,23 @@
function table.deepcopy(object) function table.deepcopy(object)
-- keep track of already seen objects to avoid loops -- keep track of already seen objects to avoid loops
local seen = {} local seen = {}
local function copy(object) local function copy(object)
if type(object) ~= "table" then if type(object) ~= "table" then
return object return object
elseif seen[object] then elseif seen[object] then
return seen[object] return seen[object]
end end
local clone = {} local clone = {}
seen[object] = clone seen[object] = clone
for key, value in pairs(object) do for key, value in pairs(object) do
clone[key] = copy(value) clone[key] = copy(value)
end end
return clone return clone
end end
return copy(object) return copy(object)
end end
@ -72,8 +72,8 @@
end end
return result return result
end end
-- --
-- Flattens a hierarchy of tables into a single array containing all -- Flattens a hierarchy of tables into a single array containing all
@ -81,23 +81,48 @@
-- --
function table.flatten(arr) function table.flatten(arr)
local result = { } local result = {}
local function flatten(arr) local function flatten(arr)
for _, v in ipairs(arr) do local n = #arr
for i = 1, n do
local v = arr[i]
if type(v) == "table" then if type(v) == "table" then
flatten(v) flatten(v)
else elseif v then
table.insert(result, v) table.insert(result, v)
end end
end end
end end
flatten(arr) flatten(arr)
return result return result
end end
--
-- Walk the elements of an array and call the specified function
-- for each non-nil element. This works around a "feature" of the
-- ipairs() function that stops iteration at the first nil.
--
-- @param arr
-- The array to iterate.
-- @param func
-- The function to call. The value (not the index) will be passed
-- as the only argument.
--
function table.foreachi(arr, func)
local n = #arr
for i = 1, n do
local v = arr[i]
if v then
func(v)
end
end
end
-- --
-- Merge two lists into an array of objects, containing pairs -- Merge two lists into an array of objects, containing pairs
-- of values, one from each list. -- of values, one from each list.
@ -136,7 +161,7 @@
-- --
-- Inserts a value of array of values into a table. If the value is -- Inserts a value of array of values into a table. If the value is
-- itself a table, its contents are enumerated and added instead. So -- itself a table, its contents are enumerated and added instead. So
-- these inputs give these outputs: -- these inputs give these outputs:
-- --
-- "x" -> { "x" } -- "x" -> { "x" }
@ -229,7 +254,7 @@
if tbl[i] == obj then if tbl[i] == obj then
return i return i
end end
end end
end end
@ -253,5 +278,5 @@
end end
return result return result
end end