检查包含来自 table 的项目的字符串
Checking string containing item from table
if FirstName:GetValue() == ""
or table.HasValue( Blocked, string.lower(FirstName:GetValue())) then
-- Checks if the name contains any "bad" words, or nothing was typed in.
FirstNameCHECK = false
text4:SetText("Bad Name")
text4:SetColor(Color(255,0,0,255))
else
FirstNameCHECK = true
text4:SetText("Good Name")
text4:SetColor(Color(0,255,0,255))
end
此代码当前检查字符串是否与 table 中的条目完全相同。
我如何才能更改此代码,以便它检查插入的字符串(FirstName 变量)是否包含来自 table 的条目之一?
低效的解决方案是遍历 table 并在每个元素上调用 string.find
。对于非常大的 tables,这种方法可能会变得非常慢,因为您必须检查每个元素,但除非您处理的是非常大的数据集,否则可能会非常好。
一种更聪明的方法是使用由子字符串索引的嵌套 table。例如,您可以有一个根 table,索引为 a
到 z
。你用你的单词的第一个字母索引到 table,你会得到另一个相同结构的 table。这个你用第二个字母索引,依此类推,直到你在你正在检查的字母上找不到更多 table,或者你到达了单词的末尾。在后一种情况下,您可能需要在 table 中添加一个唯一条目,以指示您要查找的确切单词是否在 table 中(因为没有更多字母,您需要能够以某种方式检查它)。
这种方法有几个缺点。构建 table 可能会占用大量内存,并且执行检查可能比针对较小的 table 的天真方法要慢得多。此外,操作查找 table 也不是那么简单(例如,考虑从中删除一个词)。所以这种结构实际上只对执行查找有用,你应该坚持使用正常的 tables 来完成其他任务。
例如,您可能希望在查找 table 中维护对真实数据中条目的引用列表 table,它允许您从特定前缀字符串中获取所有匹配的条目数据 table.
在其他一些问题中解决了这类问题(适用于多维表)- Loop until find 2 specific values in a table?
function MultiTableSearch(input,value,case,index_check)
if (input and type(input) == 'table') then
if (type(value) == 'table' and value == input) then
return true;
end
for key,object in pairs(input) do
if (index_check) then
if (case and type(input)=='string' and type(key)=='string') then
if (value:lower() == key:lower()) then -- to avoid exit the loop
return true;
end
else
if (key == value) then
return true
elseif(type(object)=='table') then
return MultiTableSearch(object,value,case,index_check)
end
end
else
if (case and type(value)=='string' and type(object) == 'string') then
if (value:lower() == object:lower()) then
return true;
end
elseif(type(object)=='table') then
if (value == object) then
return true;
else
return MultiTableSearch(object,value,case)
end
else
if (object == value) then
return true;
end
end
end
end
end
return false;
end
并使用调用这个
MultiTableSearch(blocked,FirstName:GetValue(),true) -- table,name,case(true to ignore case)
if FirstName:GetValue() == ""
or table.HasValue( Blocked, string.lower(FirstName:GetValue())) then
-- Checks if the name contains any "bad" words, or nothing was typed in.
FirstNameCHECK = false
text4:SetText("Bad Name")
text4:SetColor(Color(255,0,0,255))
else
FirstNameCHECK = true
text4:SetText("Good Name")
text4:SetColor(Color(0,255,0,255))
end
此代码当前检查字符串是否与 table 中的条目完全相同。
我如何才能更改此代码,以便它检查插入的字符串(FirstName 变量)是否包含来自 table 的条目之一?
低效的解决方案是遍历 table 并在每个元素上调用 string.find
。对于非常大的 tables,这种方法可能会变得非常慢,因为您必须检查每个元素,但除非您处理的是非常大的数据集,否则可能会非常好。
一种更聪明的方法是使用由子字符串索引的嵌套 table。例如,您可以有一个根 table,索引为 a
到 z
。你用你的单词的第一个字母索引到 table,你会得到另一个相同结构的 table。这个你用第二个字母索引,依此类推,直到你在你正在检查的字母上找不到更多 table,或者你到达了单词的末尾。在后一种情况下,您可能需要在 table 中添加一个唯一条目,以指示您要查找的确切单词是否在 table 中(因为没有更多字母,您需要能够以某种方式检查它)。
这种方法有几个缺点。构建 table 可能会占用大量内存,并且执行检查可能比针对较小的 table 的天真方法要慢得多。此外,操作查找 table 也不是那么简单(例如,考虑从中删除一个词)。所以这种结构实际上只对执行查找有用,你应该坚持使用正常的 tables 来完成其他任务。
例如,您可能希望在查找 table 中维护对真实数据中条目的引用列表 table,它允许您从特定前缀字符串中获取所有匹配的条目数据 table.
在其他一些问题中解决了这类问题(适用于多维表)- Loop until find 2 specific values in a table?
function MultiTableSearch(input,value,case,index_check)
if (input and type(input) == 'table') then
if (type(value) == 'table' and value == input) then
return true;
end
for key,object in pairs(input) do
if (index_check) then
if (case and type(input)=='string' and type(key)=='string') then
if (value:lower() == key:lower()) then -- to avoid exit the loop
return true;
end
else
if (key == value) then
return true
elseif(type(object)=='table') then
return MultiTableSearch(object,value,case,index_check)
end
end
else
if (case and type(value)=='string' and type(object) == 'string') then
if (value:lower() == object:lower()) then
return true;
end
elseif(type(object)=='table') then
if (value == object) then
return true;
else
return MultiTableSearch(object,value,case)
end
else
if (object == value) then
return true;
end
end
end
end
end
return false;
end
并使用调用这个
MultiTableSearch(blocked,FirstName:GetValue(),true) -- table,name,case(true to ignore case)