Search code examples
luaiterationlua-tablelistiterator

Is it possible to make an iterator in Lua that can iterate over a dictionary?


Lets say that I have a dictionary in Lua (i.e. a Lua table that contains indexes of type string) like so:

local my_dictionary = {a = 123; b = 321; c = 456; d = 654};

What I am trying to do is create an iterator function that can iterate over a table even if its indexes are of type string; kind of like pairs, however whenever I try to call next() to get the next index,value it will only return the index,value if the index is of type int. An idea I had was maybe to call (index):byte(1, -1) and add up the tuple of ints, and use that as a sort of pretend index, just to keep track of the indexes, but I do not think that would work with next. Here is basically what I have so far:

local function each(list)
    if #list > 0 then
        local function my_itr(lst, ind)
            return next(lst, ind);
        end
        return my_itr, List, 0;
    end
    return function() end, nil, nil;
end

this only works for a table with int indexes (an array table), so I was wondering if anyone could help me out. Thanks. Edit: To make this less vague here is an example piece of code of what I am trying to accomplish:

local mytable = {a = 123; b = 321; 3, 2, 1, c = "bca"};
for i,v in each(mytable) do
    print(i,v);
end

what it should output:

>a 123
>b 321
>1 3
>2 2
>3 1
>c bca

The output would not have to be in exact order.


Solution

  • It should work exactly as you want it to with a couple of tweaks: fix typo in List and pass nil instead of 0:

    local function each(list)
      local function my_itr(lst, ind)
        return next(lst, ind)
      end
      return my_itr, list, nil
    end
    
    local mytable = {a = 123; b = 321; 3, 2, 1, c = "bca"}
    for i,v in each(mytable) do
      print(i,v)
    end
    

    This prints the following for me, which is what you'd need:

    1   3
    2   2
    3   1
    a   123
    b   321
    c   bca