2 -- Copyright (C) 2008-2010 Matthew Wild
3 -- Copyright (C) 2008-2010 Waqas Hussain
5 -- This project is MIT/X11 licensed. Please see the
6 -- COPYING file in the source package for more information.
13 local t_insert
= table.insert
;
14 local select
, next = select
, next;
15 local unpack
= table.unpack
or unpack
; --luacheck: ignore 113 143
16 local pack
= table.pack
or function (...) return { n
= select("#", ...), ... }; end -- luacheck: ignore 143
18 local table, setmetatable
= table, setmetatable
;
23 -- Reverse an iterator
24 function it
.reverse(f
, s
, var
)
27 -- First call the normal iterator
29 local ret
= { f(s
, var
) };
31 if var
== nil then break; end
32 t_insert(results
, 1, ret
);
35 -- Then return our reverse one
36 local i
,max = 0, #results
;
37 return function (_results
)
40 return unpack(_results
[i
]);
45 -- Iterate only over keys in a table
46 local function _keys_it(t
, key
)
47 return (next(t
, key
));
53 -- Iterate only over values in a table
57 key
, val
= next(_t
, key
);
62 -- Iterate over the n:th return value
63 function it
.select(n
, f
, s
, var
)
65 local ret
= pack(f(_s
, var
));
71 -- Given an iterator, iterate only over unique items
72 function it
.unique(f
, s
, var
)
77 local ret
= pack(f(s
, var
));
79 if var
== nil then break; end
82 return unpack(ret
, 1, ret
.n
);
88 --[[ Return the number of items an iterator returns ]]--
89 function it
.count(f
, s
, var
)
94 if var
== nil then break; end
101 -- Return the first n items an iterator returns
102 function it
.head(n
, f
, s
, var
)
104 return function (_s
, _var
)
113 -- Skip the first n items an iterator returns
114 function it
.skip(n
, f
, s
, var
)
121 -- Return the last n items an iterator returns
122 function it
.tail(n
, f
, s
, var
)
123 local results
, count
= {}, 0;
125 local ret
= pack(f(s
, var
));
127 if var
== nil then break; end
128 results
[(count
%n
)+1] = ret
;
132 if n
> count
then n
= count
; end
137 if pos
> n
then return nil; end
138 local ret
= results
[((count
-1+pos
)%n
)+1];
139 return unpack(ret
, 1, ret
.n
);
141 --return reverse(head(n, reverse(f, s, var))); -- !
144 function it
.filter(filter
, f
, s
, var
)
145 if type(filter
) ~= "function" then
146 local filter_value
= filter
;
147 function filter(x
) return x
~= filter_value
; end
149 return function (_s
, _var
)
151 repeat ret
= pack(f(_s
, _var
));
153 until _var
== nil or filter(unpack(ret
, 1, ret
.n
));
154 return unpack(ret
, 1, ret
.n
);
158 local function _ripairs_iter(t
, key
) if key
> 1 then return key
-1, t
[key
-1]; end end
159 function it
.ripairs(t
)
160 return _ripairs_iter
, t
, #t
+1;
163 local function _range_iter(max, curr
) if curr
< max then return curr
+ 1; end end
164 function it
.range(x
, y
)
165 if not y
then x
, y
= 1, x
; end -- Default to 1..x if y not given
166 return _range_iter
, y
, x
-1;
169 -- Convert the values returned by an iterator to an array
170 function it
.to_array(f
, s
, var
)
174 if var
== nil then break; end
180 function it
.sorted_pairs(t
, sort_func
)
181 local keys
= it
.to_array(it
.keys(t
));
182 table.sort(keys
, sort_func
);
193 -- Treat the return of an iterator as key,value pairs,
195 function it
.to_table(f
, s
, var
)
198 var
, var2
= f(s
, var
);
199 if var
== nil then break; end
205 local function _join_iter(j_s
, j_var
)
206 local iterators
, current_idx
= j_s
[1], j_s
[2];
207 local f
, s
, var
= unpack(iterators
[current_idx
], 1, 3);
211 local ret
= pack(f(s
, var
));
214 -- End of this iterator, advance to next
215 if current_idx
== #iterators
then
216 -- No more iterators, return nil
219 j_s
[2] = current_idx
+ 1;
220 return _join_iter(j_s
);
222 return unpack(ret
, 1, ret
.n
);
224 local join_methods
= {};
226 __index
= join_methods
;
227 __call
= function (t
, s
, var
) --luacheck: ignore 212/t
228 return _join_iter(s
, var
);
232 function join_methods
:append(f
, s
, var
)
233 table.insert(self
, { f
, s
, var
});
234 return self
, { self
, 1 };
237 function join_methods
:prepend(f
, s
, var
)
238 table.insert(self
, { f
, s
, var
}, 1);
239 return self
, { self
, 1 };
242 function it
.join(f
, s
, var
)
243 return setmetatable({ {f
, s
, var
} }, join_mt
);