【问题标题】:Loop over first n elements of Lua table循环 Lua 表的前 n 个元素
【发布时间】:2023-04-02 07:56:01
【问题描述】:

我有一个 for 循环,其中我正在执行一些我只想最多执行 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,因此不能使用它来代替计数器。

【问题讨论】:

  • 您对目前的方法有什么顾虑?
  • 您还可以更改 GetAllUnits() 以接受要返回的最大项目数作为参数。因此,您有效地移动 GetAllUnits() 中的“if ..break”代码
  • @tonypdmtr 呃,“全部”不是意味着不同的东西吗?
  • 我觉得没有更好的办法了。
  • @tonypdmtr 即使 OP 可以修改GetAllUnits,限制它返回的单位数量也可能会改变循环的结果,因为不会考虑类别条件(仅限nameCount计算不属于“结构”或“命令”类别的单位)。

标签: loops lua


【解决方案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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-11-26
    • 2019-09-05
    • 1970-01-01
    • 2012-08-22
    • 2012-10-02
    • 1970-01-01
    • 2014-12-20
    • 2021-06-26
    相关资源
    最近更新 更多