util/iterators.lua
author Matthew Wild <mwild1@gmail.com>
Sun, 25 Sep 2011 00:20:43 +0100
changeset 4386 ce769240f8ec
parent 3540 bc139431830b
child 4441 a01b7207cb37
permissions -rw-r--r--
util.iterators: Add range(from, to)
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1522
569d58d21612 Add copyright header to those files missing one
Matthew Wild <mwild1@gmail.com>
parents: 919
diff changeset
     1
-- Prosody IM
2923
b7049746bd29 Update copyright headers for 2010
Matthew Wild <mwild1@gmail.com>
parents: 1660
diff changeset
     2
-- Copyright (C) 2008-2010 Matthew Wild
b7049746bd29 Update copyright headers for 2010
Matthew Wild <mwild1@gmail.com>
parents: 1660
diff changeset
     3
-- Copyright (C) 2008-2010 Waqas Hussain
1522
569d58d21612 Add copyright header to those files missing one
Matthew Wild <mwild1@gmail.com>
parents: 919
diff changeset
     4
-- 
569d58d21612 Add copyright header to those files missing one
Matthew Wild <mwild1@gmail.com>
parents: 919
diff changeset
     5
-- This project is MIT/X11 licensed. Please see the
569d58d21612 Add copyright header to those files missing one
Matthew Wild <mwild1@gmail.com>
parents: 919
diff changeset
     6
-- COPYING file in the source package for more information.
569d58d21612 Add copyright header to those files missing one
Matthew Wild <mwild1@gmail.com>
parents: 919
diff changeset
     7
--
569d58d21612 Add copyright header to those files missing one
Matthew Wild <mwild1@gmail.com>
parents: 919
diff changeset
     8
919
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     9
--[[ Iterators ]]--
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    10
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    11
-- Reverse an iterator
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    12
function reverse(f, s, var)
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    13
	local results = {};
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    14
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    15
	-- First call the normal iterator
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    16
	while true do
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    17
		local ret = { f(s, var) };
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    18
		var = ret[1];
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    19
	        if var == nil then break; end
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    20
		table.insert(results, 1, ret);
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    21
	end
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    22
	
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    23
	-- Then return our reverse one
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    24
	local i,max = 0, #results;
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    25
	return function (results)
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    26
			if i<max then
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    27
				i = i + 1;
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    28
				return unpack(results[i]);
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    29
			end
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    30
		end, results;
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    31
end
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    32
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    33
-- Iterate only over keys in a table
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    34
local function _keys_it(t, key)
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    35
	return (next(t, key));
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    36
end
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    37
function keys(t)
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    38
	return _keys_it, t;
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    39
end
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    40
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    41
-- Iterate only over values in a table
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    42
function values(t)
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    43
	local key, val;
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    44
	return function (t)
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    45
		key, val = next(t, key);
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    46
		return val;
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    47
	end, t;
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    48
end
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    49
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    50
-- Given an iterator, iterate only over unique items
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    51
function unique(f, s, var)
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    52
	local set = {};
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    53
	
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    54
	return function ()
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    55
		while true do
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    56
			local ret = { f(s, var) };
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    57
			var = ret[1];
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    58
		        if var == nil then break; end
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    59
		        if not set[var] then
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    60
				set[var] = true;
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    61
				return var;
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    62
			end
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    63
		end
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    64
	end;
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    65
end
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    66
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    67
--[[ Return the number of items an iterator returns ]]--
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    68
function count(f, s, var)
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    69
	local x = 0;
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    70
	
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    71
	while true do
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    72
		local ret = { f(s, var) };
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    73
		var = ret[1];
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    74
	        if var == nil then break; end
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    75
		x = x + 1;
3540
bc139431830b Monster whitespace commit (beware the whitespace monster).
Waqas Hussain <waqas20@gmail.com>
parents: 3392
diff changeset
    76
	end
919
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    77
	
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    78
	return x;
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    79
end
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    80
1659
6092fc9b078b util.iterators: Add head() iterator, to return the first n items
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
    81
-- Return the first n items an iterator returns
6092fc9b078b util.iterators: Add head() iterator, to return the first n items
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
    82
function head(n, f, s, var)
6092fc9b078b util.iterators: Add head() iterator, to return the first n items
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
    83
	local c = 0;
6092fc9b078b util.iterators: Add head() iterator, to return the first n items
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
    84
	return function (s, var)
6092fc9b078b util.iterators: Add head() iterator, to return the first n items
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
    85
		if c >= n then
6092fc9b078b util.iterators: Add head() iterator, to return the first n items
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
    86
			return nil;
6092fc9b078b util.iterators: Add head() iterator, to return the first n items
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
    87
		end
6092fc9b078b util.iterators: Add head() iterator, to return the first n items
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
    88
		c = c + 1;
6092fc9b078b util.iterators: Add head() iterator, to return the first n items
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
    89
		return f(s, var);
6092fc9b078b util.iterators: Add head() iterator, to return the first n items
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
    90
	end, s;
6092fc9b078b util.iterators: Add head() iterator, to return the first n items
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
    91
end
6092fc9b078b util.iterators: Add head() iterator, to return the first n items
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
    92
3392
6e31b49c4ab8 util.iterators: Add skip() to skip the first n items of an iterator
Matthew Wild <mwild1@gmail.com>
parents: 2923
diff changeset
    93
-- Skip the first n items an iterator returns
6e31b49c4ab8 util.iterators: Add skip() to skip the first n items of an iterator
Matthew Wild <mwild1@gmail.com>
parents: 2923
diff changeset
    94
function skip(n, f, s, var)
6e31b49c4ab8 util.iterators: Add skip() to skip the first n items of an iterator
Matthew Wild <mwild1@gmail.com>
parents: 2923
diff changeset
    95
	for i=1,n do
6e31b49c4ab8 util.iterators: Add skip() to skip the first n items of an iterator
Matthew Wild <mwild1@gmail.com>
parents: 2923
diff changeset
    96
		var = f(s, var);
6e31b49c4ab8 util.iterators: Add skip() to skip the first n items of an iterator
Matthew Wild <mwild1@gmail.com>
parents: 2923
diff changeset
    97
	end
6e31b49c4ab8 util.iterators: Add skip() to skip the first n items of an iterator
Matthew Wild <mwild1@gmail.com>
parents: 2923
diff changeset
    98
	return f, s, var;
6e31b49c4ab8 util.iterators: Add skip() to skip the first n items of an iterator
Matthew Wild <mwild1@gmail.com>
parents: 2923
diff changeset
    99
end
6e31b49c4ab8 util.iterators: Add skip() to skip the first n items of an iterator
Matthew Wild <mwild1@gmail.com>
parents: 2923
diff changeset
   100
6e31b49c4ab8 util.iterators: Add skip() to skip the first n items of an iterator
Matthew Wild <mwild1@gmail.com>
parents: 2923
diff changeset
   101
-- Return the last n items an iterator returns
1660
ae2f60a20428 util.iterators: Add tail() iterator, to return the last n items
Matthew Wild <mwild1@gmail.com>
parents: 1659
diff changeset
   102
function tail(n, f, s, var)
ae2f60a20428 util.iterators: Add tail() iterator, to return the last n items
Matthew Wild <mwild1@gmail.com>
parents: 1659
diff changeset
   103
	local results, count = {}, 0;
ae2f60a20428 util.iterators: Add tail() iterator, to return the last n items
Matthew Wild <mwild1@gmail.com>
parents: 1659
diff changeset
   104
	while true do
ae2f60a20428 util.iterators: Add tail() iterator, to return the last n items
Matthew Wild <mwild1@gmail.com>
parents: 1659
diff changeset
   105
		local ret = { f(s, var) };
ae2f60a20428 util.iterators: Add tail() iterator, to return the last n items
Matthew Wild <mwild1@gmail.com>
parents: 1659
diff changeset
   106
		var = ret[1];
ae2f60a20428 util.iterators: Add tail() iterator, to return the last n items
Matthew Wild <mwild1@gmail.com>
parents: 1659
diff changeset
   107
	        if var == nil then break; end
ae2f60a20428 util.iterators: Add tail() iterator, to return the last n items
Matthew Wild <mwild1@gmail.com>
parents: 1659
diff changeset
   108
		results[(count%n)+1] = ret;
ae2f60a20428 util.iterators: Add tail() iterator, to return the last n items
Matthew Wild <mwild1@gmail.com>
parents: 1659
diff changeset
   109
		count = count + 1;
ae2f60a20428 util.iterators: Add tail() iterator, to return the last n items
Matthew Wild <mwild1@gmail.com>
parents: 1659
diff changeset
   110
	end
ae2f60a20428 util.iterators: Add tail() iterator, to return the last n items
Matthew Wild <mwild1@gmail.com>
parents: 1659
diff changeset
   111
ae2f60a20428 util.iterators: Add tail() iterator, to return the last n items
Matthew Wild <mwild1@gmail.com>
parents: 1659
diff changeset
   112
	if n > count then n = count; end
ae2f60a20428 util.iterators: Add tail() iterator, to return the last n items
Matthew Wild <mwild1@gmail.com>
parents: 1659
diff changeset
   113
ae2f60a20428 util.iterators: Add tail() iterator, to return the last n items
Matthew Wild <mwild1@gmail.com>
parents: 1659
diff changeset
   114
	local pos = 0;
ae2f60a20428 util.iterators: Add tail() iterator, to return the last n items
Matthew Wild <mwild1@gmail.com>
parents: 1659
diff changeset
   115
	return function ()
ae2f60a20428 util.iterators: Add tail() iterator, to return the last n items
Matthew Wild <mwild1@gmail.com>
parents: 1659
diff changeset
   116
		pos = pos + 1;
ae2f60a20428 util.iterators: Add tail() iterator, to return the last n items
Matthew Wild <mwild1@gmail.com>
parents: 1659
diff changeset
   117
		if pos > n then return nil; end
ae2f60a20428 util.iterators: Add tail() iterator, to return the last n items
Matthew Wild <mwild1@gmail.com>
parents: 1659
diff changeset
   118
		return unpack(results[((count-1+pos)%n)+1]);
ae2f60a20428 util.iterators: Add tail() iterator, to return the last n items
Matthew Wild <mwild1@gmail.com>
parents: 1659
diff changeset
   119
	end
ae2f60a20428 util.iterators: Add tail() iterator, to return the last n items
Matthew Wild <mwild1@gmail.com>
parents: 1659
diff changeset
   120
	--return reverse(head(n, reverse(f, s, var)));
ae2f60a20428 util.iterators: Add tail() iterator, to return the last n items
Matthew Wild <mwild1@gmail.com>
parents: 1659
diff changeset
   121
end
ae2f60a20428 util.iterators: Add tail() iterator, to return the last n items
Matthew Wild <mwild1@gmail.com>
parents: 1659
diff changeset
   122
4386
ce769240f8ec util.iterators: Add range(from, to)
Matthew Wild <mwild1@gmail.com>
parents: 3540
diff changeset
   123
local function _range_iter(max, curr) if curr < max then return curr + 1; end end
ce769240f8ec util.iterators: Add range(from, to)
Matthew Wild <mwild1@gmail.com>
parents: 3540
diff changeset
   124
function range(x, y)
ce769240f8ec util.iterators: Add range(from, to)
Matthew Wild <mwild1@gmail.com>
parents: 3540
diff changeset
   125
	if not y then x, y = 1, x; end -- Default to 1..x if y not given
ce769240f8ec util.iterators: Add range(from, to)
Matthew Wild <mwild1@gmail.com>
parents: 3540
diff changeset
   126
	return _range_iter, y, x-1;
ce769240f8ec util.iterators: Add range(from, to)
Matthew Wild <mwild1@gmail.com>
parents: 3540
diff changeset
   127
end
ce769240f8ec util.iterators: Add range(from, to)
Matthew Wild <mwild1@gmail.com>
parents: 3540
diff changeset
   128
919
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   129
-- Convert the values returned by an iterator to an array
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   130
function it2array(f, s, var)
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   131
	local t, var = {};
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   132
	while true do
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   133
		var = f(s, var);
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   134
	        if var == nil then break; end
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   135
		table.insert(t, var);
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   136
	end
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   137
	return t;
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   138
end
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   139
3540
bc139431830b Monster whitespace commit (beware the whitespace monster).
Waqas Hussain <waqas20@gmail.com>
parents: 3392
diff changeset
   140
-- Treat the return of an iterator as key,value pairs,
919
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   141
-- and build a table
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   142
function it2table(f, s, var)
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   143
	local t, var = {};
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   144
	while true do
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   145
		var, var2 = f(s, var);
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   146
	        if var == nil then break; end
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   147
		t[var] = var2;
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   148
	end
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   149
	return t;
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   150
end
4386
ce769240f8ec util.iterators: Add range(from, to)
Matthew Wild <mwild1@gmail.com>
parents: 3540
diff changeset
   151