Lua итератор в массив - PullRequest
       2

Lua итератор в массив

5 голосов
/ 29 ноября 2011

На языке 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

Ответы [ 3 ]

10 голосов
/ 29 ноября 2011

Для него нет стандартной библиотечной функции.Но на самом деле написать довольно просто:

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

local myArr = BuildArray(<iterator function call>)

Это будет только , если ваша функция итератора возвращает отдельные элементы.Если он возвращает несколько элементов, вам придется сделать что-то другое.

1 голос
/ 30 ноября 2011

Как сказал Ник Болас, нет стандартной библиотечной функции, которая выполняет желаемое действие.

Вот служебная функция, расширяющая библиотеку 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 можно найти здесь

0 голосов
/ 30 ноября 2011

Если вы просто хотите автоматически увеличивать ключ таблицы для каждого элемента данных, вы можете использовать table.insert (collection, item) - это добавит элемент в коллекцию и установит ключ для счетчика коллекции + 1

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...