diff options
Diffstat (limited to 'util/iterators.lua')
-rw-r--r-- | util/iterators.lua | 96 |
1 files changed, 62 insertions, 34 deletions
diff --git a/util/iterators.lua b/util/iterators.lua index 1f6aacb8..bd150ff2 100644 --- a/util/iterators.lua +++ b/util/iterators.lua @@ -1,7 +1,7 @@ -- 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. -- @@ -10,6 +10,11 @@ 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 it.reverse(f, s, var) local results = {}; @@ -18,18 +23,18 @@ function it.reverse(f, s, var) while true do local ret = { f(s, var) }; var = ret[1]; - if var == nil then break; end - table.insert(results, 1, ret); + if var == nil then break; end + t_insert(results, 1, ret); end - + -- Then return our reverse one local i,max = 0, #results; - return function (results) - if i<max then - i = i + 1; - return unpack(results[i]); - end - end, results; + return function (_results) + if i<max then + i = i + 1; + return unpack(_results[i]); + end + end, results; end -- Iterate only over keys in a table @@ -43,24 +48,33 @@ end -- Iterate only over values in a table function it.values(t) local key, val; - return function (t) - key, val = next(t, key); + return function (_t) + key, val = next(_t, key); return val; end, t; end +-- Iterate over the n:th return value +function it.select(n, f, s, var) + return function (_s) + local ret = pack(f(_s, var)); + var = ret[1]; + return ret[n]; + end, s, var; +end + -- Given an iterator, iterate only over unique items function it.unique(f, s, var) local set = {}; - + return function () while true do - local ret = { f(s, var) }; + local ret = pack(f(s, var)); var = ret[1]; - if var == nil then break; end - if not set[var] then + if var == nil then break; end + if not set[var] then set[var] = true; - return var; + return unpack(ret, 1, ret.n); end end end; @@ -69,32 +83,31 @@ end --[[ Return the number of items an iterator returns ]]-- function it.count(f, s, var) local x = 0; - + while true do - local ret = { f(s, var) }; - var = ret[1]; - if var == nil then break; end + var = f(s, var); + if var == nil then break; end x = x + 1; end - + return x; end -- Return the first n items an iterator returns function it.head(n, f, s, var) local c = 0; - return function (s, var) + return function (_s, _var) if c >= n then return nil; end c = c + 1; - return f(s, var); - end, s; + return f(_s, _var); + end, s, var; end -- Skip the first n items an iterator returns function it.skip(n, f, s, var) - for i=1,n do + for _ = 1, n do var = f(s, var); end return f, s, var; @@ -104,9 +117,9 @@ end 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 + if var == nil then break; end results[(count%n)+1] = ret; count = count + 1; end @@ -117,9 +130,24 @@ function it.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 @@ -135,11 +163,11 @@ end -- Convert the values returned by an iterator to an array function it.to_array(f, s, var) - local t, var = {}; + local t = {}; while true do var = f(s, var); - if var == nil then break; end - table.insert(t, var); + if var == nil then break; end + t_insert(t, var); end return t; end @@ -150,7 +178,7 @@ function it.to_table(f, s, var) local t, var2 = {}; while true do var, var2 = f(s, var); - if var == nil then break; end + if var == nil then break; end t[var] = var2; end return t; |