2016-04-23 101 views
0

我有一個for循環,我正在做一些我最多隻想執行的操作。到目前爲止,我通過循環中增加的局部變量來完成此操作,並且每次都檢查它是否超出了計數器限制。如果確實如此,我會跳出循環。循環Lua表的前n個元素

for _,u in GetAllUnits() do 
     if not u:IsInCategory("STRUCTURE") and not u:IsInCategory("COMMAND") then 
       NameUnit(u) 
       nameCount = nameCount + 1 
       if nameCount >= maxUnitNames then break end 
     end 
end 

我對Lua很新,想知道是否有更好的方法來做到這一點。重要的是,我最終不會創建表格副本或其他昂貴的操作。

請注意,_包含單位的ID,所以這不能用來代替計數器。

+0

您對目前的方法有什麼擔心? –

+1

您也可以改變GetAllUnits()以接受作爲參數返回的最大項數。所以,你有效地將'if .. break'代碼移入GetAllUnits() – tonypdmtr

+0

@tonypdmtr呃,不是「All」意味着什麼不同? –

回答

1

如果您擔心這段代碼的強制性質,可以隨時使用普通功能的方法:

local function notStructureNotCommand(_, u) 
    return not u:IsInCategory("STRUCTURE") and 
     not u:IsInCategory("COMMAND") 
end 

for _,u in take(maxUnitNames, filter(notStructureNotCommand, GetAllUnits())) do 
    NameUnit(u) 
end 

您可以在Lua做函數式編程相當不錯,但你必須要在外部庫中尋找像mapfilter等通常的幫助函數。在LuaRocks存儲庫中有很多這些函數的實現,但在你的情況下,你必須確保你得到一個在迭代器上工作的版本,而不是(或者除了表)。如果您沒有找到合適的東西,您可以使用以下功能:

local filter 
do 
    local function filter_helper(pred, f, s, var_1, ...) 
    if var_1 ~= nil then 
     if pred(var_1, ...) then 
     return var_1, ... 
     else 
     return filter_helper(pred, f, s, f(s, var_1)) 
     end 
    end 
    end 

    function filter(pred, f, s, var) 
    return function(st, v) 
     return filter_helper(pred, f, st, f(st, v)) 
    end, s, var 
    end 
end 


local function take(n, f, s, var) 
    return function(st, v) 
    if n > 0 then 
     n = n - 1 
     return f(st, v) 
    end 
    end, s, var 
end