循环直到在表中找到2个特定的值? [英] Loop until find 2 specific values in a table?

查看:131
本文介绍了循环直到在表中找到2个特定的值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图找到一个更聪明的方法来解决这个问题。

这是一个与游戏相关的代码摘录,它循环每个槽背包直到它找到一把铲子和一根绳索

 本地继续
本地foundShovel,foundRope
for i = 0,Container.GetLast():Index()do - 循环槽背包
本地cont =容器(i)
为j = 0,cont:ItemCount() - 1 do - 循环槽插槽
本地id = cont:GetItemData(j).id - 获取该插槽的ID
foundShovel,foundRope = GetToolIndex(id,0)或foundShovel,GetToolIndex(id,1)或foundRope - 令人困惑...
如果foundShovel和foundRope然后
continue = true
break
end
end
如果继续然后
- 做某事我需要做
结束
结束
结束
- Swi把ID转换成对应的索引:
函数GetToolIndex(id,retrn)
本地shovel = {
[9598] = 4, - 重击的命运
[9599] = 4 (挤塞)
[9596] = 3, - 挤压女孩的装备
[9597] = 3, - 挤压女孩装备(卡住)
[ 9594] = 2, - 精英狡猾的刺杀
[9595] = 2, - 偷偷摸摸的精英(卡住)刺杀
[5710] = 1, - 轻铲
[3457 ] = 0 - 铲
}
本地绳= {
[646] = 1, - elvenhair绳
[3003] = 0, - 绳
[9598] = 4, - 命运
[9599] = 4的重击式钻孔机 - 命运(卡住)
[9596] = 3的重击式钻孔器 - 挤压女孩力量
[9597] = 3, - 挤压女孩(干扰)齿轮
[9594] = 2, - 偷偷摸摸的精英分子
[9595] = 2 - 偷偷摸摸的精英(堵塞)
}
如果修复== 0,则
返回shovel [id]
elseif return == 1 then
retrn rope [id]
end
end

但是它没有工作,我想这种方法一定有更好的方法,如果我需要在表格中找到X值,而不是2呢?那么,在表格中存储所有数据要好得多,而不是调用一个函数函数获取容器数据。

无论如何,这里是一个脚本,将获得所有的背包ID,将它们存储在一个表中,然后调用你每个ID的函数。

  Backpack = {data = {}}; 
函数背包:更新(刷新)
if(#self.data == 0或refresh)然后
for i = 0,Container.GetLast():Index()do
本地cont =集装箱(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; - 比table.insert更快
end
end
end
end
函数背包:refresh()
self:update(true)
结束
函数背包:find(func,...) - 如果id是好的,func应该返回一个值,否则为false,添加额外的参数用函数
调用if(not func)then
返回false;
结束
self:update(); - 包含没有库存数据;
for key,value成对(self.data)do
local value = func(value,...); - 使用'cached'用户清单的id(作为第一个参数)调用函数
if(value)then
返回值
结束
结束
返回假;
end

例子:

<$
[9598] = 4, - 重击的命运
[9599] = 4 (挤塞)
[9596] = 3, - 挤压女孩的装备
[9597] = 3, - 挤压女孩装备(卡住)
[ 9594] = 2, - 精英狡猾的刺杀
[9595] = 2, - 偷偷摸摸的精英(卡住)刺杀
[5710] = 1, - 轻铲
[3457 ] = 0 - 铲
}
本地绳= {
[646] = 1, - elvenhair绳
[3003] = 0, - 绳
[9598] = 4, - 命运
[9599] = 4的重击式钻孔机 - 命运(卡住)
[9596] = 3的重击式钻孔器 - 挤压女孩力量
[9597] = 3, - 挤压女孩(干扰)齿轮
[9594] = 2, - 偷偷摸摸的精英分子
[9595] = 2 - 偷偷摸摸的精英(堵塞)
}
如果返回== 0然后
返回shovel [id]
elseif返回== 1然后
返回rope [id]
end
end

函数Test()
本地铲,rope =背包:find(GetToolIndex,0),背包:find(GetToolIndex,1)
if(铲子和绳索)then
print(铲和绳子存在);
end
end
Test();

编辑

想了一会儿,你似乎试图检查用户是否具有该特定的ID。

这是另一种方法,它将检查所有用户的背包数据表搜索),它会搜索基于表键或表值,它也会在嵌套表上工作,这应该设置你的好。

  Backpack = {data = {}}; 
函数背包:更新(刷新)
if(#self.data == 0或refresh)然后
for i = 0,Container.GetLast():Index()do
本地cont =集装箱(i);对于j = 0,
,cont:ItemCount() - 1 do
local data = cont:GetItemData(j); - 很确定这会返回一个表
self.data [data.id] = data; - self.data [9598] = {...}
结束
结束
结束$ b $结束
函数背包:refresh()
self:更新(true)
结束
函数Backpack:MultiTableSearch(input,value,case,index_check)
if(input and type(input)=='table')then
if (type(value)=='table'和value == input)然后
返回true;
end
对于键,输入对象做
if(index_check)then
if(case and type(input)=='string'and type(key) =='string')then
if(value:lower()== key:lower())然后 - 避免退出循环
return true;
end

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
返回self:MultiTableSearch(object,value,case)
end
else
if(object == value)then
return true;
end
end
end
end
end
return false;
end
函数背包:exists(value,case,index_check)
self:update();
返回self:MultiTableSearch(self.data,value,case,index_check)
end
- 检查值9598,不区分大小写设置为false,
- index_checking设置为true(检查表索引 - > Backpack.data [9598],如果它被设置,它将返回true);
if(Backpack:exists(9598,false,true))然后
print(User has whacking driller of fate);
end
if(Backpack:exists(Doom of Doom))然后 - 将尝试找到任何具有末日铲子的表值(区分大小写)
打印(厄运的铲子);如果您担心MultiTableSearch的性能(因为它看起来像一个
$ b

函数

 <$ c $如果(输入和类型(输入)=='表')然后
如果(类型(值)=='表'和值= =输入),那么
返回true;
end
对于键,输入对象做
if(index_check)then
if(case and type(input)=='string'and type(key) =='string')then
if(value:lower()== key:lower())然后 - 避免退出循环
return true;
end

if(key == value)then
return true
elseif(type(object)=='table')then
return MultiTableSearch(object,value,case,index_check)
end
end
else $ b $ if(case and type(value)=='string'and type(object)=='字符串')然后
if(value:lower()== object:lower())then
return true;
end
elseif(type(object)=='table')then
if(value == object)then
return true;
else
返回MultiTableSearch(object,value,case)
end
else
if(object == value)then
return true;
end
end
end
end
end
return false;
end

测试(将值附加到表中并扫描嵌套表,废话表大小)

 本地start_time = os.clock(); 
t = {}
for i = 1,500,000 do --500k table size
t [i] = i-1
end
print(os.clock() -start_time) - 0.05秒来创建表
local start_time = os.clock();
print(tostring(MultiTableSearch(t,500000,false))) - 将尝试找到一个值为500,000
print(os.clock() - start_time) - 0.197sec sec扫描整个表

函数nestedTable(object,times) - 创建嵌套表 - >对象= {{{.. n次}}}}
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) - >将在表格内创建15000次。
print(os.clock() - start_time) - 0.007 sec创建嵌套表
local start_time = os.clock();
print(tostring(MultiTableSearch(t,1,false))) - 将尝试查找1(作为表值),最后一个表值
print(os.clock() - start_time) - 0.014秒找到嵌套表中的值


I was trying to find a more clever way to solve this.

This is an excerpt from a code related to a game, it loops trough each slot of each backpack untill it finds a shovel and a rope

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

But its not working, and i was thinking there must be a better way for this approach, what if i need to find X values within a table instead of just 2? I hope my issue could be understood here.

解决方案

Well, storing all data in tables is much more better,rather than calling a function to get containers data.

Anyhow here's a script that will get all backpack id's, store them in a table and then just call you function with each 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

Example:

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();

EDIT:

After thinking a while, you seem to try to check if user has that specific id.

Here's another method, that will check all all user backpack data (deep table search), it will search based on table key or table value, it will work on nested tables too, this should set you good.

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

If you're worried about the performance of the MultiTableSearch (because it looks a bit heavy), it's pretty fast, ran several tests.

Function

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

Tests (appending values into a table and scanning nested tables, both tests are in nonsense table sizes)

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

这篇关于循环直到在表中找到2个特定的值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆