90 lines
2.0 KiB
Lua

--- Iterator library.
-- @module Iter
local Iter = {}
Iter.pairs = pairs
Iter.ipairs = ipairs
function Iter.spairs(t, order)
-- collect the keys
local keys = {}
for k in pairs(t) do
keys[#keys + 1] = k
end
-- if order function given, sort by it by passing the table and keys a, b,
-- otherwise just sort the keys
if order then
table.sort(
keys,
function(a, b)
return order(t, a, b)
end
)
else
table.sort(keys)
end
-- return the iterator function
local i = 0
return function()
i = i + 1
if keys[i] then
return keys[i], t[keys[i]]
end
end
end
function Iter.top(t, stop)
local start = #t
stop = stop or 1
return function()
if start >= stop and t[start] ~= nil then
local cur = start
start = start - 1
return cur, t[cur]
end
return nil
end
end
function Iter.wrap(t, start, reverse)
--[[
-- Returns an iterator that iterates over integer keys in table `t` from the specified start position, wrapping
-- around and ending when it reaches `start` again.
--
-- `dir` specifies the direction to iterate (negative values for reverse, otherwise forward)
-- `start` specifies the start location. If `nil`, the first returned item will be at the at the start of the table
-- (or the end of the table, if `dir` is negative)
--
-- Behavior if the table changes size during iteration is undefined.
]]
local dir = (reverse and -1) or 1
local len = #t
local i = start
start = start or (reverse and len) or 1
return function()
if i == nil then
i = start
return i, t[i]
end
i = i + dir
if i < 1 then
i = i + len
elseif i > len then
i = i - len
end
if i == start then
return nil
end
return i, t[i]
end
end
return Iter