X-Git-Url: https://git.enpas.org/?a=blobdiff_plain;f=util%2Fiterators.lua;h=4b429163bfbdbcf963cf0d267c1d3da7b1015ac7;hb=4253ee98b95deab76f21352bb05eb6af07004604;hp=318c1a96b8fad3b45f1d7111ef130d98ab34e8f0;hpb=4643eae0bf41b461c9337bfb66f9ac80f7e84f11;p=prosody.git diff --git a/util/iterators.lua b/util/iterators.lua index 318c1a96..d453a694 100644 --- a/util/iterators.lua +++ b/util/iterators.lua @@ -1,15 +1,22 @@ -- Prosody IM -- Copyright (C) 2008-2010 Matthew Wild -- Copyright (C) 2008-2010 Waqas Hussain --- +-- -- This project is MIT/X11 licensed. Please see the -- COPYING file in the source package for more information. -- --[[ Iterators ]]-- +local it = {}; + +local t_insert = table.insert; +local select, next = select, next; +local unpack = table.unpack or unpack; --luacheck: ignore 113 +local pack = table.pack or function (...) return { n = select("#", ...), ... }; end + -- Reverse an iterator -function reverse(f, s, var) +function it.reverse(f, s, var) local results = {}; -- First call the normal iterator @@ -17,15 +24,15 @@ function reverse(f, s, var) local ret = { f(s, var) }; var = ret[1]; if var == nil then break; end - table.insert(results, 1, ret); + t_insert(results, 1, ret); end - + -- Then return our reverse one local i,max = 0, #results; - return function (results) + return function (_results) if i= n then return nil; end c = c + 1; - return f(s, var); - end, s; + return f(_s, _var); + end, s, var; end -function tail(n, f, s, var) +-- Skip the first n items an iterator returns +function it.skip(n, f, s, var) + for _ = 1, n do + var = f(s, var); + end + return f, s, var; +end + +-- Return the last n items an iterator returns +function it.tail(n, f, s, var) local results, count = {}, 0; while true do - local ret = { f(s, var) }; + local ret = pack(f(s, var)); var = ret[1]; if var == nil then break; end results[(count%n)+1] = ret; @@ -106,26 +121,52 @@ function tail(n, f, s, var) return function () pos = pos + 1; if pos > n then return nil; end - return unpack(results[((count-1+pos)%n)+1]); + local ret = results[((count-1+pos)%n)+1]; + return unpack(ret, 1, ret.n); + end + --return reverse(head(n, reverse(f, s, var))); -- ! +end + +function it.filter(filter, f, s, var) + if type(filter) ~= "function" then + local filter_value = filter; + function filter(x) return x ~= filter_value; end end - --return reverse(head(n, reverse(f, s, var))); + return function (_s, _var) + local ret; + repeat ret = pack(f(_s, _var)); + var = ret[1]; + until var == nil or filter(unpack(ret, 1, ret.n)); + return unpack(ret, 1, ret.n); + end, s, var; +end + +local function _ripairs_iter(t, key) if key > 1 then return key-1, t[key-1]; end end +function it.ripairs(t) + return _ripairs_iter, t, #t+1; +end + +local function _range_iter(max, curr) if curr < max then return curr + 1; end end +function it.range(x, y) + if not y then x, y = 1, x; end -- Default to 1..x if y not given + return _range_iter, y, x-1; end -- Convert the values returned by an iterator to an array -function it2array(f, s, var) - local t, var = {}; +function it.to_array(f, s, var) + local t = {}; while true do var = f(s, var); if var == nil then break; end - table.insert(t, var); + t_insert(t, var); end return t; end --- Treat the return of an iterator as key,value pairs, +-- Treat the return of an iterator as key,value pairs, -- and build a table -function it2table(f, s, var) - local t, var = {}; +function it.to_table(f, s, var) + local t, var2 = {}; while true do var, var2 = f(s, var); if var == nil then break; end @@ -133,3 +174,5 @@ function it2table(f, s, var) end return t; end + +return it;