iterators.lua

1
-- Prosody IM
2
-- Copyright (C) 2008-2010 Matthew Wild
3
-- Copyright (C) 2008-2010 Waqas Hussain
4
-- 
5
-- This project is MIT/X11 licensed. Please see the
6
-- COPYING file in the source package for more information.
7
--
8
 
9
--[[ Iterators ]]--
10
 
11
-- Reverse an iterator
12
function reverse(f, s, var)
13
	local results = {};
14
 
15
	-- First call the normal iterator
16
	while true do
17
		local ret = { f(s, var) };
18
		var = ret[1];
19
	        if var == nil then break; end
20
		table.insert(results, 1, ret);
21
	end
22
	
23
	-- Then return our reverse one
24
	local i,max = 0, #results;
25
	return function (results)
26
			if i<max then
27
				i = i + 1;
28
				return unpack(results[i]);
29
			end
30
		end, results;
31
end
32
 
33
-- Iterate only over keys in a table
34
local function _keys_it(t, key)
35
	return (next(t, key));
36
end
37
function keys(t)
38
	return _keys_it, t;
39
end
40
 
41
-- Iterate only over values in a table
42
function values(t)
43
	local key, val;
44
	return function (t)
45
		key, val = next(t, key);
46
		return val;
47
	end, t;
48
end
49
 
50
-- Given an iterator, iterate only over unique items
51
function unique(f, s, var)
52
	local set = {};
53
	
54
	return function ()
55
		while true do
56
			local ret = { f(s, var) };
57
			var = ret[1];
58
		        if var == nil then break; end
59
		        if not set[var] then
60
				set[var] = true;
61
				return var;
62
			end
63
		end
64
	end;
65
end
66
 
67
--[[ Return the number of items an iterator returns ]]--
68
function count(f, s, var)
69
	local x = 0;
70
	
71
	while true do
72
		local ret = { f(s, var) };
73
		var = ret[1];
74
	        if var == nil then break; end
75
		x = x + 1;
76
	end	
77
	
78
	return x;
79
end
80
 
81
-- Return the first n items an iterator returns
82
function head(n, f, s, var)
83
	local c = 0;
84
	return function (s, var)
85
		if c >= n then
86
			return nil;
87
		end
88
		c = c + 1;
89
		return f(s, var);
90
	end, s;
91
end
92
 
93
-- Skip the first n items an iterator returns
94
function skip(n, f, s, var)
95
	for i=1,n do
96
		var = f(s, var);
97
	end
98
	return f, s, var;
99
end
100
 
101
-- Return the last n items an iterator returns
102
function tail(n, f, s, var)
103
	local results, count = {}, 0;
104
	while true do
105
		local ret = { f(s, var) };
106
		var = ret[1];
107
	        if var == nil then break; end
108
		results[(count%n)+1] = ret;
109
		count = count + 1;
110
	end
111
 
112
	if n > count then n = count; end
113
 
114
	local pos = 0;
115
	return function ()
116
		pos = pos + 1;
117
		if pos > n then return nil; end
118
		return unpack(results[((count-1+pos)%n)+1]);
119
	end
120
	--return reverse(head(n, reverse(f, s, var)));
121
end
122
 
123
-- Convert the values returned by an iterator to an array
124
function it2array(f, s, var)
125
	local t, var = {};
126
	while true do
127
		var = f(s, var);
128
	        if var == nil then break; end
129
		table.insert(t, var);
130
	end
131
	return t;
132
end
133
 
134
-- Treat the return of an iterator as key,value pairs, 
135
-- and build a table
136
function it2table(f, s, var)
137
	local t, var = {};
138
	while true do
139
		var, var2 = f(s, var);
140
	        if var == nil then break; end
141
		t[var] = var2;
142
	end
143
	return t;
144
end