【问题标题】:Lua iterator to arrayLua 迭代器到数组
【发布时间】:2012-01-09 02:48:08
【问题描述】:

用 Lua 的说法,是否有任何语法糖可以将迭代器函数转换为数组(重复调用,结果存储在升序索引中),也许在标准库中?

我正在标记一个属于协议的字符串,并且需要对字符串开头的元素进行位置访问,而字符串的结尾是一个变体集合。

代码(特定于我的用例)如下,我很难相信它不在标准库中:d

local array_tokenise = function (line)
    local i = 1;
    local array = {};

    for item in string.gmatch(line,"%w+") do
      array[i] = item;
      i = i +1
    end

    return array
  end

【问题讨论】:

    标签: lua


    【解决方案1】:

    它没有标准库函数。但实际上,写起来很简单:

    function BuildArray(...)
      local arr = {}
      for v in ... do
        arr[#arr + 1] = v
      end
      return arr
    end
    
    local myArr = BuildArray(<iterator function call>)
    

    只有在您的迭代器函数返回单个元素时才有效。如果它返回多个元素,则您必须做一些不同的事情。

    【讨论】:

    • 重要的行也可以写成table.insert(arr, v),根据你的喜好,它可能更易读。不过不确定性能影响。
    • :(moooo,我猜我应该和 nutrasweet 有关系,谢谢你的回答。
    • @KevinBallard,这会严重影响性能。事实上,最有效的方法是增加一个索引变量i——每次迭代仍然是一个加法操作,但没有# 操作。
    • @KevinBallard trac.caspring.org/wiki/LuaPerformance a[#a+1] = x 在 223% 的时间内执行为 a[i] = x; i = i+1(一百万次迭代为 0.453 对 0.203 秒。)相比之下,table.insert(a, x) 在 1.25 秒内执行,这是一个主要的性能损失。
    • @KevinBallard 我的结果,在 Linux 上使用 100 万次迭代,Lua 5.1.4,Core i5 为 2.53 ghz:pastebin.com/QSu099ri 1000 万次迭代:pastebin.com/yMbABu5m5000 万次迭代:@ 987654324@这似乎证实了你的结果。
    【解决方案2】:

    正如 Nicol Bolas 所说,没有标准库函数可以执行您想要的操作。

    这是一个扩展 table 库的实用函数:

    function table.build(build_fn, iterator_fn, state, ...)
        build_fn = (
                build_fn
            or  function(arg)
                    return arg
                end
        )
        local res, res_i = {}, 1
        local vars = {...}
        while true do
            vars = {iterator_fn(state, vars[1])}
            if vars[1] == nil then break end
            --build_fn(unpack(vars)) -- see http://trac.caspring.org/wiki/LuaPerformance : TEST 3
            res[res_i] = build_fn(vars)
            res_i = res_i+1
        end
        return res
    end
    

    以下是一些演示用法的示例代码:

    require"stringify"
    
    local t1 = {4, 5, 6, {"crazy cake!"}}
    local t2 = {a = "x", b = "y", c = "z"}
    print(stringify(table.build(nil, pairs(t1))))
    print(stringify(table.build(nil, pairs(t2))))
    print(stringify(table.build(
            function(arg) -- arg[1] = k, arg[2] = v
                return tostring(arg[1]).." = "..tostring(arg[2])
            end
        ,   pairs(t1)
    )))
    
    local poetry = [[
        Roses are red, violets are blue.
        I like trains, and so do you!
    
        By the way, oranges are orange.
        Also! Geez, I almost forgot...
        Lemons are yellow.
    ]]
    print(stringify(table.build(
            function(arg) -- arg[1] == plant, arg[2] == colour
                return (
                        string.upper(string.sub(arg[1], 1, 1))..string.lower(string.sub(arg[1], 2))
                    ..  " is "
                    ..  string.upper(arg[2]).."!"
                )
            end
        ,   string.gmatch(poetry, "(%a+)s are (%a+)")
    )))
    

    输出:

    {
        [1] = {
            [1] = 1,
            [2] = 4,
        },
        [2] = {
            [1] = 2,
            [2] = 5,
        },
        [3] = {
            [1] = 3,
            [2] = 6,
        },
        [4] = {
            [1] = 4,
            [2] = {
                [1] = "crazy cake!",
            },
        },
    }
    {
        [1] = {
            [1] = "a",
            [2] = "x",
        },
        [2] = {
            [1] = "c",
            [2] = "z",
        },
        [3] = {
            [1] = "b",
            [2] = "y",
        },
    }
    {
        [1] = "1 = 4",
        [2] = "2 = 5",
        [3] = "3 = 6",
        [4] = "4 = table: 00450BE8",
    }
    {
        [1] = "Rose is RED!",
        [2] = "Violet is BLUE!",
        [3] = "Orange is ORANGE!",
        [4] = "Lemon is YELLOW!",
    }
    

    stringify.lua可以找到here

    【讨论】:

      【解决方案3】:

      如果您只是想为每个数据元素自动增加表键,您可以使用 table.insert(collection, item) - 这会将项目附加到集合并将键设置为集合计数 + 1

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-08-12
        • 2017-11-03
        • 1970-01-01
        • 2021-11-25
        • 2018-12-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多