【发布时间】:2018-09-19 20:23:56
【问题描述】:
我正在设计一个通用表过滤器,它可以从给定表中删除条目,问题是键不是唯一的来完成此操作,并且类型也不同。
让我用一个例子更清楚地说明
SampleTable = {
{ key1 = 10, key2 = 'name_1', Str = 'sample_string_1' },
{ key1 = 10, key2 = 'name_3', Str = 'sample_string_2' },
{ key1 = 11, key2 = 'name_2', Mac = {'ID1', 'ID2', 'ID3'} },
{ key1 = 11, key2 = 'name_2', Mac = {'ID1'} },
{ key1 = 12, key2 = 'name_4', Mac = {'ID2', 'ID3'} }
}
function filter(inputTable, ...)
filterItems = {...}
end
我想传递任意数量的键来过滤这个表
local key1 = 11
local Mac = 'ID1'
filter(SampleTable, key1, Mac)
-- Should return -> { key1 = 11, key2 = 'name_2', Mac = 'ID1'},
key1 = 12
Mac = 'ID3'
filter(SampleTable, key1, Mac)
-- Should return -> { key1 = 12, key2 = 'name_4', Mac = ID3'}
key1 = 11
Mac = 'ID2'
filter(SampleTable, key1, Mac)
-- Should return both
-- { key1 = 11, key2 = 'name_2', Mac = ID2'},
-- { key1 = 11, key2 = 'name_5', Mac = ID2'},
key1 = 10
Str = 'sample_string_2'
filter(SampleTable, key1, Str)
-- Should return { key1 = 10, key2 = 'name_3', Str = 'sample_string_2'}
我目前的解决方案是搜索两个表中的每个键值对
function filter(tIn, tFilter)
local retain = true
local exist = nil
local tOut = tIn
local _findInTable = function (t, k, v)
if(not t[k]) then return true
elseif(t[k] and t[k] == v) then return true
else return false end
end
for i, t in ipairs (tIn) do
for k,v in pairs (tFilter) do
exist = _findInTable(t, k, v)
retain = retain and exist
end
if not retain then tOut[i] = nil end
retain = true
end
return tOut
end
local myTable = filter(SampleTable, {key1 = 11, Mac = 'ID1'})
问题是我无法预见递归将如何提供帮助。
这段代码在我有以下 SampleTable 时有效,正如您所见,Mac 不是我的代码的子表。
SampleTable = {
{ key1 = 10, key2 = 'name_1', Str = 'sample_string_1' },
{ key1 = 10, key2 = 'name_3', Str = 'sample_string_2' },
{ key1 = 11, key2 = 'name_2', Mac = 'ID1' }
-- { key1 = 11, key2 = 'name_2', Mac = {'ID1', 'ID2', 'ID3'} },
-- { key1 = 11, key2 = 'name_2', Mac = {'ID1'} },
-- { key1 = 12, key2 = 'name_4', Mac = {'ID2', 'ID3'} }
}
【问题讨论】:
-
您是否尝试按名称查看每个键?如果您想以不同方式处理不同的键,那将是有意义的。
-
这是一般问题和对功能的模糊描述。您尝试了什么,什么没有奏效?
-
我目前的解决方案,希望有更好的描述。我一直在寻找递归解决方案。