Lua 迭代器到数组

发布于 2024-12-18 12:57:29 字数 380 浏览 0 评论 0原文

用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

In Lua parlance, is there any syntactic sugar for turning an iterator function into an array (repeated invocations with results stored in ascending indices), perhaps something in the standard library ?

I'm tokenizing a string belonging to a protocol and need to to have positional access to elements at the start of the string, and the end of the string is a variant collection.

The code (specific to my use-case) is as follows, I find it hard to believe that it isn't in the standard library :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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

请远离我 2024-12-25 12:57:29

没有标准库函数。但实际上,编写起来非常简单:

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

local myArr = BuildArray(<iterator function call>)

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

There's no standard library function for it. But really, it's pretty trivial to write:

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

local myArr = BuildArray(<iterator function call>)

This will only work if your iterator function returns single elements. If it returns multiple elements, you'd have to do something different.

染墨丶若流云 2024-12-25 12:57:29

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

if you are just looking to auto-increment the table key for each data element, you can use table.insert(collection, item) - this will append the item to the collection and sets the key to the collection count + 1

温暖的光 2024-12-25 12:57:29

正如 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 https://web.archive.org/web/20120708033619/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 可以找到 此处

As Nicol Bolas said, there is no standard library function that performs the action you desire.

Here is a utility function that extends the table library:

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 https://web.archive.org/web/20120708033619/http://trac.caspring.org/wiki/LuaPerformance : TEST 3
        res[res_i] = build_fn(vars)
        res_i = res_i+1
    end
    return res
end

Here is some example code demonstrating usage:

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+)")
)))

Output:

{
    [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 can be found here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文