Loops 循环直到在表中找到2个特定值?
我试图找到一个更聪明的方法来解决这个问题 这是一段与游戏相关的代码摘录,它在每个背包的每个插槽中循环,直到找到一把铲子和一根绳子Loops 循环直到在表中找到2个特定值?,loops,search,for-loop,lua,Loops,Search,For Loop,Lua,我试图找到一个更聪明的方法来解决这个问题 这是一段与游戏相关的代码摘录,它在每个背包的每个插槽中循环,直到找到一把铲子和一根绳子 local continue local foundShovel, foundRope for i = 0, Container.GetLast():Index() do -- looping trough backpacks local cont = Container(i) for j = 0, cont:I
local continue
local foundShovel, foundRope
for i = 0, Container.GetLast():Index() do -- looping trough backpacks
local cont = Container(i)
for j = 0, cont:ItemCount()-1 do -- looping trough each slot
local id = cont:GetItemData(j).id -- Getting ID of that slot
foundShovel, foundRope = GetToolIndex(id,0) or foundShovel,GetToolIndex(id,1) or foundRope -- confusing...
if foundShovel and foundRope then
continue = true
break
end
end
if continue then
-- do something i need to do
end
end
end
-- Switches ID to corresponding index :
function GetToolIndex(id,retrn)
local shovel = {
[9598] = 4 , -- whacking driller of fate
[9599]= 4 , -- whacking driller of fate(jammed)
[9596]= 3 , -- squeezing gear of girlpower
[9597]= 3 , -- squeezing gear of girlpower(jammed)
[9594]= 2 , -- sneaky stabber of elitenesss
[9595]= 2 , -- sneaky stabber of elitenesss(jammed)
[5710]= 1, -- light shovel
[3457] = 0 -- shovel
}
local rope = {
[646]= 1, -- elvenhair rope
[3003] = 0, -- rope
[9598] = 4 , -- whacking driller of fate
[9599]= 4 , -- whacking driller of fate(jammed)
[9596]= 3 , -- squeezing gear of girlpower
[9597]= 3 , -- squeezing gear of girlpower(jammed)
[9594]= 2 , -- sneaky stabber of elitenesss
[9595]= 2 -- sneaky stabber of elitenesss(jammed)
}
if retrn == 0 then
return shovel[id]
elseif return == 1 then
retrn rope[id]
end
end
但它不起作用,我在想,对于这种方法,一定有更好的方法,如果我需要在一个表中找到X值,而不是2,该怎么办?我希望这里能理解我的问题。好吧,将所有数据存储在表中比调用函数获取容器数据要好得多 无论如何,这里有一个脚本,它将获取所有背包id,将它们存储在一个表中,然后用每个id调用函数
Backpack = {data = {}};
function Backpack:update(refresh)
if(#self.data==0 or refresh) then
for i = 0, Container.GetLast():Index() do
local cont = Container(i);
for j = 0,cont:ItemCount()-1 do
--table.insert(self.data,cont:GetItemData(j).id)
self.data[#self.data+1] = cont:GetItemData(j).id; -- faster than table.insert
end
end
end
end
function Backpack:refresh()
self:update(true)
end
function Backpack:find(func,...) -- func should return a value if id is good, otherwise false, add extra args to call with the function
if (not func) then
return false;
end
self:update(); -- Incase there is no inventory data;
for key,value in pairs(self.data) do
local value = func(value,...); -- calls the function with the id (as first parameter) of the 'cached' user inventory
if (value) then
return value
end
end
return false;
end
例如:
function GetToolIndex(id,return)
local shovel = {
[9598] = 4 , -- whacking driller of fate
[9599]= 4 , -- whacking driller of fate(jammed)
[9596]= 3 , -- squeezing gear of girlpower
[9597]= 3 , -- squeezing gear of girlpower(jammed)
[9594]= 2 , -- sneaky stabber of elitenesss
[9595]= 2 , -- sneaky stabber of elitenesss(jammed)
[5710]= 1, -- light shovel
[3457] = 0 -- shovel
}
local rope = {
[646]= 1, -- elvenhair rope
[3003] = 0, -- rope
[9598] = 4 , -- whacking driller of fate
[9599]= 4 , -- whacking driller of fate(jammed)
[9596]= 3 , -- squeezing gear of girlpower
[9597]= 3 , -- squeezing gear of girlpower(jammed)
[9594]= 2 , -- sneaky stabber of elitenesss
[9595]= 2 -- sneaky stabber of elitenesss(jammed)
}
if return == 0 then
return shovel[id]
elseif return == 1 then
return rope[id]
end
end
function Test()
local shovel,rope = Backpack:find(GetToolIndex,0),Backpack:find(GetToolIndex,1)
if (shovel and rope) then
print("Shovel and rope exist");
end
end
Test();
编辑:
思考了一会儿之后,您似乎试图检查用户是否具有该特定id
这里还有另一种方法,它将检查所有用户背包数据(深度表搜索),它将根据表键或表值进行搜索,它也将在嵌套表上工作,这应该对您有好处
Backpack = {data = {}};
function Backpack:update(refresh)
if(#self.data==0 or refresh) then
for i = 0, Container.GetLast():Index() do
local cont = Container(i);
for j = 0,cont:ItemCount()-1 do
local data = cont:GetItemData(j); -- pretty sure this returns a table
self.data[data.id] = data; -- self.data[9598] = {...}
end
end
end
end
function Backpack:refresh()
self:update(true)
end
function Backpack: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 self: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 self:MultiTableSearch(object,value,case)
end
else
if (object == value) then
return true;
end
end
end
end
end
return false;
end
function Backpack:exists(value,case,index_check)
self:update();
return self:MultiTableSearch(self.data,value,case,index_check)
end
-- checks the value 9598, case-insensitive is set to false,
-- index_checking is set to true (checks table index --> Backpack.data[9598], if it was set it'll return true);
if (Backpack:exists(9598,false,true)) then
print("User has whacking driller of fate");
end
if (Backpack:exists("Shovel of doom")) then -- will try to find any table-value that has the of "Shovel of doom" (case-sensitive)
print("User Shovel of doom");
end
“如果您担心MultiTableSearch的性能(因为它看起来有点重),它的速度非常快,”运行了几个测试
作用
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
测试(将值追加到表中并扫描嵌套表,这两个测试都是无意义的表大小)
如果return==0,我很惊讶。你能确认游戏索引的内容是基于0而不是基于1的吗?是的,非常确定它是从0开始的。我没有这样做,因为我想在找到它们时停止,以避免不必要的错误actions@mojimi,返回值将退出循环,最好是在数组(表)中处理项,它们是我写过的另一个方法中最快的。
local start_time = os.clock();
t = {}
for i=1,500000 do --500k table size
t[i]=i-1
end
print(os.clock()-start_time) -- 0.05 sec to create the table
local start_time = os.clock();
print(tostring(MultiTableSearch(t,500000,false)))-- will try to find a key with the value of 500,000
print(os.clock()-start_time) -- 0.197sec sec to scan the whole table
function nestedTable(object,times) -- creates nested table -> object={{{{..n times}}}}
if (times > 0 ) then
object[#object+1] = {times = times}
return (nestedTable(object[#object],times-1))
end
end
local start_time = os.clock();
t = {};
nestedTable(t,15000) --> will create table inside a table x 15000 times.
print(os.clock()-start_time) -- 0.007 sec to create the nested table
local start_time = os.clock();
print(tostring(MultiTableSearch(t,1,false)))-- will try to find a 1 (as a table value), the very last table value
print(os.clock()-start_time) -- 0.014 sec to find the value in the nested table