Comparison

util/iterators.lua @ 6054:7a5ddbaf758d

Merge 0.9->0.10
author Matthew Wild <mwild1@gmail.com>
date Wed, 02 Apr 2014 17:41:38 +0100
parent 5776:bd0ff8ae98a8
child 7184:dedc6bf180e2
comparison
equal deleted inserted replaced
6053:2f93a04564b2 6054:7a5ddbaf758d
1 -- Prosody IM 1 -- Prosody IM
2 -- Copyright (C) 2008-2010 Matthew Wild 2 -- Copyright (C) 2008-2010 Matthew Wild
3 -- Copyright (C) 2008-2010 Waqas Hussain 3 -- Copyright (C) 2008-2010 Waqas Hussain
4 -- 4 --
5 -- This project is MIT/X11 licensed. Please see the 5 -- This project is MIT/X11 licensed. Please see the
6 -- COPYING file in the source package for more information. 6 -- COPYING file in the source package for more information.
7 -- 7 --
8 8
9 --[[ Iterators ]]-- 9 --[[ Iterators ]]--
10 10
11 local it = {}; 11 local it = {};
12
13 local t_insert = table.insert;
14 local select, unpack, next = select, unpack, next;
15 local function pack(...) return { n = select("#", ...), ... }; end
12 16
13 -- Reverse an iterator 17 -- Reverse an iterator
14 function it.reverse(f, s, var) 18 function it.reverse(f, s, var)
15 local results = {}; 19 local results = {};
16 20
17 -- First call the normal iterator 21 -- First call the normal iterator
18 while true do 22 while true do
19 local ret = { f(s, var) }; 23 local ret = { f(s, var) };
20 var = ret[1]; 24 var = ret[1];
21 if var == nil then break; end 25 if var == nil then break; end
22 table.insert(results, 1, ret); 26 t_insert(results, 1, ret);
23 end 27 end
24 28
25 -- Then return our reverse one 29 -- Then return our reverse one
26 local i,max = 0, #results; 30 local i,max = 0, #results;
27 return function (results) 31 return function (results)
28 if i<max then 32 if i<max then
29 i = i + 1; 33 i = i + 1;
50 end 54 end
51 55
52 -- Given an iterator, iterate only over unique items 56 -- Given an iterator, iterate only over unique items
53 function it.unique(f, s, var) 57 function it.unique(f, s, var)
54 local set = {}; 58 local set = {};
55 59
56 return function () 60 return function ()
57 while true do 61 while true do
58 local ret = { f(s, var) }; 62 local ret = pack(f(s, var));
59 var = ret[1]; 63 var = ret[1];
60 if var == nil then break; end 64 if var == nil then break; end
61 if not set[var] then 65 if not set[var] then
62 set[var] = true; 66 set[var] = true;
63 return var; 67 return unpack(ret, 1, ret.n);
64 end 68 end
65 end 69 end
66 end; 70 end;
67 end 71 end
68 72
69 --[[ Return the number of items an iterator returns ]]-- 73 --[[ Return the number of items an iterator returns ]]--
70 function it.count(f, s, var) 74 function it.count(f, s, var)
71 local x = 0; 75 local x = 0;
72 76
73 while true do 77 while true do
74 local ret = { f(s, var) }; 78 var = f(s, var);
75 var = ret[1];
76 if var == nil then break; end 79 if var == nil then break; end
77 x = x + 1; 80 x = x + 1;
78 end 81 end
79 82
80 return x; 83 return x;
81 end 84 end
82 85
83 -- Return the first n items an iterator returns 86 -- Return the first n items an iterator returns
84 function it.head(n, f, s, var) 87 function it.head(n, f, s, var)
102 105
103 -- Return the last n items an iterator returns 106 -- Return the last n items an iterator returns
104 function it.tail(n, f, s, var) 107 function it.tail(n, f, s, var)
105 local results, count = {}, 0; 108 local results, count = {}, 0;
106 while true do 109 while true do
107 local ret = { f(s, var) }; 110 local ret = pack(f(s, var));
108 var = ret[1]; 111 var = ret[1];
109 if var == nil then break; end 112 if var == nil then break; end
110 results[(count%n)+1] = ret; 113 results[(count%n)+1] = ret;
111 count = count + 1; 114 count = count + 1;
112 end 115 end
115 118
116 local pos = 0; 119 local pos = 0;
117 return function () 120 return function ()
118 pos = pos + 1; 121 pos = pos + 1;
119 if pos > n then return nil; end 122 if pos > n then return nil; end
120 return unpack(results[((count-1+pos)%n)+1]); 123 local ret = results[((count-1+pos)%n)+1];
124 return unpack(ret, 1, ret.n);
121 end 125 end
122 --return reverse(head(n, reverse(f, s, var))); 126 --return reverse(head(n, reverse(f, s, var))); -- !
127 end
128
129 function it.filter(filter, f, s, var)
130 if type(filter) ~= "function" then
131 local filter_value = filter;
132 function filter(x) return x ~= filter_value; end
133 end
134 return function (s, var)
135 local ret;
136 repeat ret = pack(f(s, var));
137 var = ret[1];
138 until var == nil or filter(unpack(ret, 1, ret.n));
139 return unpack(ret, 1, ret.n);
140 end, s, var;
123 end 141 end
124 142
125 local function _ripairs_iter(t, key) if key > 1 then return key-1, t[key-1]; end end 143 local function _ripairs_iter(t, key) if key > 1 then return key-1, t[key-1]; end end
126 function it.ripairs(t) 144 function it.ripairs(t)
127 return _ripairs_iter, t, #t+1; 145 return _ripairs_iter, t, #t+1;
137 function it.to_array(f, s, var) 155 function it.to_array(f, s, var)
138 local t, var = {}; 156 local t, var = {};
139 while true do 157 while true do
140 var = f(s, var); 158 var = f(s, var);
141 if var == nil then break; end 159 if var == nil then break; end
142 table.insert(t, var); 160 t_insert(t, var);
143 end 161 end
144 return t; 162 return t;
145 end 163 end
146 164
147 -- Treat the return of an iterator as key,value pairs, 165 -- Treat the return of an iterator as key,value pairs,