90 lines
2.0 KiB
Lua
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
|