如何从数组中删除所有 'nil' 值?
How to remove all 'nil' values from an array?
我有一个对象数组(或只是数字),还有另一个数组,其中包含在任何情况下都不应从第一个数组中删除的所有对象。它看起来像这样:
-- Array of objects (just numbers for now)
Objects = {}
-- Array of objects that should always stay in the 'Objects' array
DontDestroyThese = {}
-- Populate the arrays
Objects[#Objects+1] = 1
Objects[#Objects+1] = 2
Objects[#Objects+1] = 3
Objects[#Objects+1] = 4
Objects[#Objects+1] = 5
DontDestroyThese[#DontDestroyThese+1] = 2
DontDestroyThese[#DontDestroyThese+1] = 5
现在,我有一个名为 destroy()
的方法,它应该从 Objects
数组中删除除包含在 DontDestroyThese
数组中的所有对象。该方法看起来像这样:
function destroy()
for I = 1, #Objects do
if(DontDestroyThese[Objects[I]] ~= nil) then
print("Skipping " .. Objects[I])
else
Objects[I] = nil
end
end
end
但是,Objects
数组现在到处都包含 nil
值。我想删除这些 nil
,这样 Objects
数组将只包含调用 destroy()
后留下的数字。我该怎么做?
最有效的方法可能是创建一个新的 table 来保存结果。尝试在数组中四处移动值可能比简单地附加到新的 table:
有更高的开销
function destroy()
local tbl = {}
for I = 1, #Objects do
if(DontDestroyThese[Objects[I]] ~= nil) then
table.insert(tbl, Objects[I])
end
end
Objects = tbl
end
此方法还意味着您不必处理要迭代的 table/array 内容的更改。
local function remove(t, pred)
for i = #t, 1, -1 do
if pred(t[i], i) then
table.remove(t, i)
end
end
return t
end
local function even(v)
return math.mod(v, 2) == 0
end
-- remove only even numbers
local t = remove({1, 2, 3, 4}, even)
-- remove values you want
local function keep(t)
return function(v)
return not t[v]
end
end
remove(Objects, keep(DontDestroyThese))
我认为解决方案要简单得多。要删除任何 nils(数组中的 'holes'),您需要做的就是使用 pairs() 迭代 table。这将跳过任何 nil,只返回您添加到新本地 table 的非 nil 值,该本地 table 在 'cleanup' 函数末尾返回。数组(tables 的索引从 1..n 开始)将保持相同的顺序。例如:
function CleanNils(t)
local ans = {}
for _,v in pairs(t) do
ans[ #ans+1 ] = v
end
return ans
end
那么你只需要这样做:
Objects = CleanNils(Objects)
测试一下:
function show(t)
for _,v in ipairs(t) do
print(v)
end
print(('='):rep(20))
end
t = {'a','b','c','d','e','f'}
t[4] = nil --create a 'hole' at 'd'
show(t) --> a b c
t = CleanNils(t) --remove the 'hole'
show(t) --> a b c e f
我有一个对象数组(或只是数字),还有另一个数组,其中包含在任何情况下都不应从第一个数组中删除的所有对象。它看起来像这样:
-- Array of objects (just numbers for now)
Objects = {}
-- Array of objects that should always stay in the 'Objects' array
DontDestroyThese = {}
-- Populate the arrays
Objects[#Objects+1] = 1
Objects[#Objects+1] = 2
Objects[#Objects+1] = 3
Objects[#Objects+1] = 4
Objects[#Objects+1] = 5
DontDestroyThese[#DontDestroyThese+1] = 2
DontDestroyThese[#DontDestroyThese+1] = 5
现在,我有一个名为 destroy()
的方法,它应该从 Objects
数组中删除除包含在 DontDestroyThese
数组中的所有对象。该方法看起来像这样:
function destroy()
for I = 1, #Objects do
if(DontDestroyThese[Objects[I]] ~= nil) then
print("Skipping " .. Objects[I])
else
Objects[I] = nil
end
end
end
但是,Objects
数组现在到处都包含 nil
值。我想删除这些 nil
,这样 Objects
数组将只包含调用 destroy()
后留下的数字。我该怎么做?
最有效的方法可能是创建一个新的 table 来保存结果。尝试在数组中四处移动值可能比简单地附加到新的 table:
有更高的开销function destroy()
local tbl = {}
for I = 1, #Objects do
if(DontDestroyThese[Objects[I]] ~= nil) then
table.insert(tbl, Objects[I])
end
end
Objects = tbl
end
此方法还意味着您不必处理要迭代的 table/array 内容的更改。
local function remove(t, pred)
for i = #t, 1, -1 do
if pred(t[i], i) then
table.remove(t, i)
end
end
return t
end
local function even(v)
return math.mod(v, 2) == 0
end
-- remove only even numbers
local t = remove({1, 2, 3, 4}, even)
-- remove values you want
local function keep(t)
return function(v)
return not t[v]
end
end
remove(Objects, keep(DontDestroyThese))
我认为解决方案要简单得多。要删除任何 nils(数组中的 'holes'),您需要做的就是使用 pairs() 迭代 table。这将跳过任何 nil,只返回您添加到新本地 table 的非 nil 值,该本地 table 在 'cleanup' 函数末尾返回。数组(tables 的索引从 1..n 开始)将保持相同的顺序。例如:
function CleanNils(t)
local ans = {}
for _,v in pairs(t) do
ans[ #ans+1 ] = v
end
return ans
end
那么你只需要这样做:
Objects = CleanNils(Objects)
测试一下:
function show(t)
for _,v in ipairs(t) do
print(v)
end
print(('='):rep(20))
end
t = {'a','b','c','d','e','f'}
t[4] = nil --create a 'hole' at 'd'
show(t) --> a b c
t = CleanNils(t) --remove the 'hole'
show(t) --> a b c e f