--- Iterator library. -- @module Utils.Iter local Iter = {} local pairs = pairs local ipairs = ipairs 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 function Iter.tpairs(...) return ipairs(type(...) == 'table' and ... or { ... }) end return Iter