util/iterators.lua
author Kim Alvefur <zash@zash.se>
Wed, 27 Mar 2024 19:33:11 +0100
changeset 13471 c2a476f4712a
parent 12748 e894677359e5
permissions -rw-r--r--
util.startup: Fix exiting on pidfile trouble prosody.shutdown() relies on prosody.main_thread, which has not been set yet at this point. Doing a clean shutdown might actually be harmful in case it tears down things set up by the conflicting Prosody, such as the very pidfile we were looking at. Thanks again SigmaTel71 for noticing
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
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 5583
diff changeset
     4
--
1522
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
4545
c9b91ddc9c11 util.iterators: Make a standard library (no longer injects into global namespace)
Matthew Wild <mwild1@gmail.com>
parents: 4441
diff changeset
    11
local it = {};
c9b91ddc9c11 util.iterators: Make a standard library (no longer injects into global namespace)
Matthew Wild <mwild1@gmail.com>
parents: 4441
diff changeset
    12
5581
167c1da54606 util.iterators: Various fixes and improvements, primarily use pack() where it should be used.
Matthew Wild <mwild1@gmail.com>
parents: 5468
diff changeset
    13
local t_insert = table.insert;
9692
eade1316728e util.iterators: Use pack from table.pack
Kim Alvefur <zash@zash.se>
parents: 9330
diff changeset
    14
local next = next;
12593
39ae08180c81 compat: Remove handling of Lua 5.1 location of 'unpack' function
Kim Alvefur <zash@zash.se>
parents: 9692
diff changeset
    15
local unpack = table.unpack;
12594
5eaf77114fdb compat: Use table.pack (there since Lua 5.2) over our util.table
Kim Alvefur <zash@zash.se>
parents: 12593
diff changeset
    16
local pack = table.pack;
8800
7b621a4a2e8d util.iterators: Add join() method and tests
Matthew Wild <mwild1@gmail.com>
parents: 8392
diff changeset
    17
local type = type;
7b621a4a2e8d util.iterators: Add join() method and tests
Matthew Wild <mwild1@gmail.com>
parents: 8392
diff changeset
    18
local table, setmetatable = table, setmetatable;
7b621a4a2e8d util.iterators: Add join() method and tests
Matthew Wild <mwild1@gmail.com>
parents: 8392
diff changeset
    19
7b621a4a2e8d util.iterators: Add join() method and tests
Matthew Wild <mwild1@gmail.com>
parents: 8392
diff changeset
    20
local _ENV = nil;
7b621a4a2e8d util.iterators: Add join() method and tests
Matthew Wild <mwild1@gmail.com>
parents: 8392
diff changeset
    21
--luacheck: std none
5581
167c1da54606 util.iterators: Various fixes and improvements, primarily use pack() where it should be used.
Matthew Wild <mwild1@gmail.com>
parents: 5468
diff changeset
    22
919
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    23
-- Reverse an iterator
4545
c9b91ddc9c11 util.iterators: Make a standard library (no longer injects into global namespace)
Matthew Wild <mwild1@gmail.com>
parents: 4441
diff changeset
    24
function it.reverse(f, s, var)
919
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    25
	local results = {};
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    26
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    27
	-- First call the normal iterator
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    28
	while true do
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    29
		local ret = { f(s, var) };
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    30
		var = ret[1];
7354
11434c46b7b7 util.iterators: Normalize indentation
Kim Alvefur <zash@zash.se>
parents: 7312
diff changeset
    31
		if var == nil then break; end
5581
167c1da54606 util.iterators: Various fixes and improvements, primarily use pack() where it should be used.
Matthew Wild <mwild1@gmail.com>
parents: 5468
diff changeset
    32
		t_insert(results, 1, ret);
919
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    33
	end
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 5583
diff changeset
    34
919
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    35
	-- Then return our reverse one
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    36
	local i,max = 0, #results;
7263
a9ef93bc81d9 util.iterators: Variable renaming to avoid shadowing [luacheck]
Matthew Wild <mwild1@gmail.com>
parents: 7261
diff changeset
    37
	return function (_results)
7354
11434c46b7b7 util.iterators: Normalize indentation
Kim Alvefur <zash@zash.se>
parents: 7312
diff changeset
    38
		if i<max then
11434c46b7b7 util.iterators: Normalize indentation
Kim Alvefur <zash@zash.se>
parents: 7312
diff changeset
    39
			i = i + 1;
11434c46b7b7 util.iterators: Normalize indentation
Kim Alvefur <zash@zash.se>
parents: 7312
diff changeset
    40
			return unpack(_results[i]);
11434c46b7b7 util.iterators: Normalize indentation
Kim Alvefur <zash@zash.se>
parents: 7312
diff changeset
    41
		end
11434c46b7b7 util.iterators: Normalize indentation
Kim Alvefur <zash@zash.se>
parents: 7312
diff changeset
    42
	end, results;
919
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    43
end
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    44
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    45
-- Iterate only over keys in a table
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    46
local function _keys_it(t, key)
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    47
	return (next(t, key));
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    48
end
4545
c9b91ddc9c11 util.iterators: Make a standard library (no longer injects into global namespace)
Matthew Wild <mwild1@gmail.com>
parents: 4441
diff changeset
    49
function it.keys(t)
919
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    50
	return _keys_it, t;
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    51
end
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    52
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    53
-- Iterate only over values in a table
4545
c9b91ddc9c11 util.iterators: Make a standard library (no longer injects into global namespace)
Matthew Wild <mwild1@gmail.com>
parents: 4441
diff changeset
    54
function it.values(t)
919
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    55
	local key, val;
7263
a9ef93bc81d9 util.iterators: Variable renaming to avoid shadowing [luacheck]
Matthew Wild <mwild1@gmail.com>
parents: 7261
diff changeset
    56
	return function (_t)
a9ef93bc81d9 util.iterators: Variable renaming to avoid shadowing [luacheck]
Matthew Wild <mwild1@gmail.com>
parents: 7261
diff changeset
    57
		key, val = next(_t, key);
919
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    58
		return val;
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    59
	end, t;
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    60
end
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    61
7358
4b4cf0167391 util.iterators: Add iterator wrapper that works like select(n, ...) applied to original iterator
Kim Alvefur <zash@zash.se>
parents: 7354
diff changeset
    62
-- Iterate over the n:th return value
4b4cf0167391 util.iterators: Add iterator wrapper that works like select(n, ...) applied to original iterator
Kim Alvefur <zash@zash.se>
parents: 7354
diff changeset
    63
function it.select(n, f, s, var)
4b4cf0167391 util.iterators: Add iterator wrapper that works like select(n, ...) applied to original iterator
Kim Alvefur <zash@zash.se>
parents: 7354
diff changeset
    64
	return function (_s)
4b4cf0167391 util.iterators: Add iterator wrapper that works like select(n, ...) applied to original iterator
Kim Alvefur <zash@zash.se>
parents: 7354
diff changeset
    65
		local ret = pack(f(_s, var));
4b4cf0167391 util.iterators: Add iterator wrapper that works like select(n, ...) applied to original iterator
Kim Alvefur <zash@zash.se>
parents: 7354
diff changeset
    66
		var = ret[1];
4b4cf0167391 util.iterators: Add iterator wrapper that works like select(n, ...) applied to original iterator
Kim Alvefur <zash@zash.se>
parents: 7354
diff changeset
    67
		return ret[n];
4b4cf0167391 util.iterators: Add iterator wrapper that works like select(n, ...) applied to original iterator
Kim Alvefur <zash@zash.se>
parents: 7354
diff changeset
    68
	end, s, var;
4b4cf0167391 util.iterators: Add iterator wrapper that works like select(n, ...) applied to original iterator
Kim Alvefur <zash@zash.se>
parents: 7354
diff changeset
    69
end
4b4cf0167391 util.iterators: Add iterator wrapper that works like select(n, ...) applied to original iterator
Kim Alvefur <zash@zash.se>
parents: 7354
diff changeset
    70
919
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    71
-- Given an iterator, iterate only over unique items
4545
c9b91ddc9c11 util.iterators: Make a standard library (no longer injects into global namespace)
Matthew Wild <mwild1@gmail.com>
parents: 4441
diff changeset
    72
function it.unique(f, s, var)
919
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    73
	local set = {};
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 5583
diff changeset
    74
919
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    75
	return function ()
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    76
		while true do
5581
167c1da54606 util.iterators: Various fixes and improvements, primarily use pack() where it should be used.
Matthew Wild <mwild1@gmail.com>
parents: 5468
diff changeset
    77
			local ret = pack(f(s, var));
919
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    78
			var = ret[1];
7354
11434c46b7b7 util.iterators: Normalize indentation
Kim Alvefur <zash@zash.se>
parents: 7312
diff changeset
    79
			if var == nil then break; end
11434c46b7b7 util.iterators: Normalize indentation
Kim Alvefur <zash@zash.se>
parents: 7312
diff changeset
    80
			if not set[var] then
919
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    81
				set[var] = true;
5581
167c1da54606 util.iterators: Various fixes and improvements, primarily use pack() where it should be used.
Matthew Wild <mwild1@gmail.com>
parents: 5468
diff changeset
    82
				return unpack(ret, 1, ret.n);
919
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    83
			end
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    84
		end
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    85
	end;
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    86
end
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    87
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    88
--[[ Return the number of items an iterator returns ]]--
4545
c9b91ddc9c11 util.iterators: Make a standard library (no longer injects into global namespace)
Matthew Wild <mwild1@gmail.com>
parents: 4441
diff changeset
    89
function it.count(f, s, var)
919
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    90
	local x = 0;
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 5583
diff changeset
    91
919
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    92
	while true do
5583
78dbece77ce8 util.iterators: Small fix for variable scoping issue
Matthew Wild <mwild1@gmail.com>
parents: 5582
diff changeset
    93
		var = f(s, var);
7354
11434c46b7b7 util.iterators: Normalize indentation
Kim Alvefur <zash@zash.se>
parents: 7312
diff changeset
    94
		if var == nil then break; end
919
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    95
		x = x + 1;
3540
bc139431830b Monster whitespace commit (beware the whitespace monster).
Waqas Hussain <waqas20@gmail.com>
parents: 3392
diff changeset
    96
	end
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 5583
diff changeset
    97
919
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    98
	return x;
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    99
end
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   100
1659
6092fc9b078b util.iterators: Add head() iterator, to return the first n items
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
   101
-- Return the first n items an iterator returns
4545
c9b91ddc9c11 util.iterators: Make a standard library (no longer injects into global namespace)
Matthew Wild <mwild1@gmail.com>
parents: 4441
diff changeset
   102
function it.head(n, f, s, var)
1659
6092fc9b078b util.iterators: Add head() iterator, to return the first n items
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
   103
	local c = 0;
7263
a9ef93bc81d9 util.iterators: Variable renaming to avoid shadowing [luacheck]
Matthew Wild <mwild1@gmail.com>
parents: 7261
diff changeset
   104
	return function (_s, _var)
1659
6092fc9b078b util.iterators: Add head() iterator, to return the first n items
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
   105
		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
   106
			return nil;
6092fc9b078b util.iterators: Add head() iterator, to return the first n items
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
   107
		end
6092fc9b078b util.iterators: Add head() iterator, to return the first n items
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
   108
		c = c + 1;
7263
a9ef93bc81d9 util.iterators: Variable renaming to avoid shadowing [luacheck]
Matthew Wild <mwild1@gmail.com>
parents: 7261
diff changeset
   109
		return f(_s, _var);
7261
b8f60dd8e99a util.iterators: Return initial var from upstream iterator [luacheck]
Matthew Wild <mwild1@gmail.com>
parents: 7260
diff changeset
   110
	end, s, var;
1659
6092fc9b078b util.iterators: Add head() iterator, to return the first n items
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
   111
end
6092fc9b078b util.iterators: Add head() iterator, to return the first n items
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
   112
3392
6e31b49c4ab8 util.iterators: Add skip() to skip the first n items of an iterator
Matthew Wild <mwild1@gmail.com>
parents: 2923
diff changeset
   113
-- Skip the first n items an iterator returns
4545
c9b91ddc9c11 util.iterators: Make a standard library (no longer injects into global namespace)
Matthew Wild <mwild1@gmail.com>
parents: 4441
diff changeset
   114
function it.skip(n, f, s, var)
7263
a9ef93bc81d9 util.iterators: Variable renaming to avoid shadowing [luacheck]
Matthew Wild <mwild1@gmail.com>
parents: 7261
diff changeset
   115
	for _ = 1, n do
3392
6e31b49c4ab8 util.iterators: Add skip() to skip the first n items of an iterator
Matthew Wild <mwild1@gmail.com>
parents: 2923
diff changeset
   116
		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
   117
	end
6e31b49c4ab8 util.iterators: Add skip() to skip the first n items of an iterator
Matthew Wild <mwild1@gmail.com>
parents: 2923
diff changeset
   118
	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
   119
end
6e31b49c4ab8 util.iterators: Add skip() to skip the first n items of an iterator
Matthew Wild <mwild1@gmail.com>
parents: 2923
diff changeset
   120
6e31b49c4ab8 util.iterators: Add skip() to skip the first n items of an iterator
Matthew Wild <mwild1@gmail.com>
parents: 2923
diff changeset
   121
-- Return the last n items an iterator returns
4545
c9b91ddc9c11 util.iterators: Make a standard library (no longer injects into global namespace)
Matthew Wild <mwild1@gmail.com>
parents: 4441
diff changeset
   122
function it.tail(n, f, s, var)
1660
ae2f60a20428 util.iterators: Add tail() iterator, to return the last n items
Matthew Wild <mwild1@gmail.com>
parents: 1659
diff changeset
   123
	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
   124
	while true do
5581
167c1da54606 util.iterators: Various fixes and improvements, primarily use pack() where it should be used.
Matthew Wild <mwild1@gmail.com>
parents: 5468
diff changeset
   125
		local ret = pack(f(s, var));
1660
ae2f60a20428 util.iterators: Add tail() iterator, to return the last n items
Matthew Wild <mwild1@gmail.com>
parents: 1659
diff changeset
   126
		var = ret[1];
7354
11434c46b7b7 util.iterators: Normalize indentation
Kim Alvefur <zash@zash.se>
parents: 7312
diff changeset
   127
		if var == nil then break; end
1660
ae2f60a20428 util.iterators: Add tail() iterator, to return the last n items
Matthew Wild <mwild1@gmail.com>
parents: 1659
diff changeset
   128
		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
   129
		count = count + 1;
ae2f60a20428 util.iterators: Add tail() iterator, to return the last n items
Matthew Wild <mwild1@gmail.com>
parents: 1659
diff changeset
   130
	end
ae2f60a20428 util.iterators: Add tail() iterator, to return the last n items
Matthew Wild <mwild1@gmail.com>
parents: 1659
diff changeset
   131
ae2f60a20428 util.iterators: Add tail() iterator, to return the last n items
Matthew Wild <mwild1@gmail.com>
parents: 1659
diff changeset
   132
	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
   133
ae2f60a20428 util.iterators: Add tail() iterator, to return the last n items
Matthew Wild <mwild1@gmail.com>
parents: 1659
diff changeset
   134
	local pos = 0;
ae2f60a20428 util.iterators: Add tail() iterator, to return the last n items
Matthew Wild <mwild1@gmail.com>
parents: 1659
diff changeset
   135
	return function ()
ae2f60a20428 util.iterators: Add tail() iterator, to return the last n items
Matthew Wild <mwild1@gmail.com>
parents: 1659
diff changeset
   136
		pos = pos + 1;
ae2f60a20428 util.iterators: Add tail() iterator, to return the last n items
Matthew Wild <mwild1@gmail.com>
parents: 1659
diff changeset
   137
		if pos > n then return nil; end
5581
167c1da54606 util.iterators: Various fixes and improvements, primarily use pack() where it should be used.
Matthew Wild <mwild1@gmail.com>
parents: 5468
diff changeset
   138
		local ret = results[((count-1+pos)%n)+1];
167c1da54606 util.iterators: Various fixes and improvements, primarily use pack() where it should be used.
Matthew Wild <mwild1@gmail.com>
parents: 5468
diff changeset
   139
		return unpack(ret, 1, ret.n);
1660
ae2f60a20428 util.iterators: Add tail() iterator, to return the last n items
Matthew Wild <mwild1@gmail.com>
parents: 1659
diff changeset
   140
	end
5582
7bc2009fdd0c util.iterators: Add filter() to run results through a filter function
Matthew Wild <mwild1@gmail.com>
parents: 5581
diff changeset
   141
	--return reverse(head(n, reverse(f, s, var))); -- !
7bc2009fdd0c util.iterators: Add filter() to run results through a filter function
Matthew Wild <mwild1@gmail.com>
parents: 5581
diff changeset
   142
end
7bc2009fdd0c util.iterators: Add filter() to run results through a filter function
Matthew Wild <mwild1@gmail.com>
parents: 5581
diff changeset
   143
7bc2009fdd0c util.iterators: Add filter() to run results through a filter function
Matthew Wild <mwild1@gmail.com>
parents: 5581
diff changeset
   144
function it.filter(filter, f, s, var)
7bc2009fdd0c util.iterators: Add filter() to run results through a filter function
Matthew Wild <mwild1@gmail.com>
parents: 5581
diff changeset
   145
	if type(filter) ~= "function" then
7bc2009fdd0c util.iterators: Add filter() to run results through a filter function
Matthew Wild <mwild1@gmail.com>
parents: 5581
diff changeset
   146
		local filter_value = filter;
7bc2009fdd0c util.iterators: Add filter() to run results through a filter function
Matthew Wild <mwild1@gmail.com>
parents: 5581
diff changeset
   147
		function filter(x) return x ~= filter_value; end
7bc2009fdd0c util.iterators: Add filter() to run results through a filter function
Matthew Wild <mwild1@gmail.com>
parents: 5581
diff changeset
   148
	end
7263
a9ef93bc81d9 util.iterators: Variable renaming to avoid shadowing [luacheck]
Matthew Wild <mwild1@gmail.com>
parents: 7261
diff changeset
   149
	return function (_s, _var)
5582
7bc2009fdd0c util.iterators: Add filter() to run results through a filter function
Matthew Wild <mwild1@gmail.com>
parents: 5581
diff changeset
   150
		local ret;
7263
a9ef93bc81d9 util.iterators: Variable renaming to avoid shadowing [luacheck]
Matthew Wild <mwild1@gmail.com>
parents: 7261
diff changeset
   151
		repeat ret = pack(f(_s, _var));
7312
471189342890 util.iterators: Fix use of incorrect variable accidentally introduced in a9ef93bc81d9
Matthew Wild <mwild1@gmail.com>
parents: 7263
diff changeset
   152
			_var = ret[1];
471189342890 util.iterators: Fix use of incorrect variable accidentally introduced in a9ef93bc81d9
Matthew Wild <mwild1@gmail.com>
parents: 7263
diff changeset
   153
		until _var == nil or filter(unpack(ret, 1, ret.n));
5582
7bc2009fdd0c util.iterators: Add filter() to run results through a filter function
Matthew Wild <mwild1@gmail.com>
parents: 5581
diff changeset
   154
		return unpack(ret, 1, ret.n);
7bc2009fdd0c util.iterators: Add filter() to run results through a filter function
Matthew Wild <mwild1@gmail.com>
parents: 5581
diff changeset
   155
	end, s, var;
1660
ae2f60a20428 util.iterators: Add tail() iterator, to return the last n items
Matthew Wild <mwild1@gmail.com>
parents: 1659
diff changeset
   156
end
ae2f60a20428 util.iterators: Add tail() iterator, to return the last n items
Matthew Wild <mwild1@gmail.com>
parents: 1659
diff changeset
   157
5468
2660407c3b73 util.iterators: Add ripairs() (ipairs() in reverse) (thanks Maranda)
Matthew Wild <mwild1@gmail.com>
parents: 4545
diff changeset
   158
local function _ripairs_iter(t, key) if key > 1 then return key-1, t[key-1]; end end
2660407c3b73 util.iterators: Add ripairs() (ipairs() in reverse) (thanks Maranda)
Matthew Wild <mwild1@gmail.com>
parents: 4545
diff changeset
   159
function it.ripairs(t)
2660407c3b73 util.iterators: Add ripairs() (ipairs() in reverse) (thanks Maranda)
Matthew Wild <mwild1@gmail.com>
parents: 4545
diff changeset
   160
	return _ripairs_iter, t, #t+1;
2660407c3b73 util.iterators: Add ripairs() (ipairs() in reverse) (thanks Maranda)
Matthew Wild <mwild1@gmail.com>
parents: 4545
diff changeset
   161
end
2660407c3b73 util.iterators: Add ripairs() (ipairs() in reverse) (thanks Maranda)
Matthew Wild <mwild1@gmail.com>
parents: 4545
diff changeset
   162
4386
ce769240f8ec util.iterators: Add range(from, to)
Matthew Wild <mwild1@gmail.com>
parents: 3540
diff changeset
   163
local function _range_iter(max, curr) if curr < max then return curr + 1; end end
4545
c9b91ddc9c11 util.iterators: Make a standard library (no longer injects into global namespace)
Matthew Wild <mwild1@gmail.com>
parents: 4441
diff changeset
   164
function it.range(x, y)
4386
ce769240f8ec util.iterators: Add range(from, to)
Matthew Wild <mwild1@gmail.com>
parents: 3540
diff changeset
   165
	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
   166
	return _range_iter, y, x-1;
ce769240f8ec util.iterators: Add range(from, to)
Matthew Wild <mwild1@gmail.com>
parents: 3540
diff changeset
   167
end
ce769240f8ec util.iterators: Add range(from, to)
Matthew Wild <mwild1@gmail.com>
parents: 3540
diff changeset
   168
919
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   169
-- Convert the values returned by an iterator to an array
4545
c9b91ddc9c11 util.iterators: Make a standard library (no longer injects into global namespace)
Matthew Wild <mwild1@gmail.com>
parents: 4441
diff changeset
   170
function it.to_array(f, s, var)
7260
425bc672d60b util.iterators: Don't replace var, as we should preserve var from the original iterator [luacheck]
Matthew Wild <mwild1@gmail.com>
parents: 7189
diff changeset
   171
	local t = {};
919
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   172
	while true do
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   173
		var = f(s, var);
7354
11434c46b7b7 util.iterators: Normalize indentation
Kim Alvefur <zash@zash.se>
parents: 7312
diff changeset
   174
		if var == nil then break; end
5581
167c1da54606 util.iterators: Various fixes and improvements, primarily use pack() where it should be used.
Matthew Wild <mwild1@gmail.com>
parents: 5468
diff changeset
   175
		t_insert(t, var);
919
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   176
	end
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   177
	return t;
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   178
end
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   179
9330
f6f1dec164b5 util.iterators: Add sorted_pairs() method
Matthew Wild <mwild1@gmail.com>
parents: 8800
diff changeset
   180
function it.sorted_pairs(t, sort_func)
f6f1dec164b5 util.iterators: Add sorted_pairs() method
Matthew Wild <mwild1@gmail.com>
parents: 8800
diff changeset
   181
	local keys = it.to_array(it.keys(t));
f6f1dec164b5 util.iterators: Add sorted_pairs() method
Matthew Wild <mwild1@gmail.com>
parents: 8800
diff changeset
   182
	table.sort(keys, sort_func);
f6f1dec164b5 util.iterators: Add sorted_pairs() method
Matthew Wild <mwild1@gmail.com>
parents: 8800
diff changeset
   183
	local i = 0;
f6f1dec164b5 util.iterators: Add sorted_pairs() method
Matthew Wild <mwild1@gmail.com>
parents: 8800
diff changeset
   184
	return function ()
f6f1dec164b5 util.iterators: Add sorted_pairs() method
Matthew Wild <mwild1@gmail.com>
parents: 8800
diff changeset
   185
		i = i + 1;
f6f1dec164b5 util.iterators: Add sorted_pairs() method
Matthew Wild <mwild1@gmail.com>
parents: 8800
diff changeset
   186
		local key = keys[i];
f6f1dec164b5 util.iterators: Add sorted_pairs() method
Matthew Wild <mwild1@gmail.com>
parents: 8800
diff changeset
   187
		if key ~= nil then
f6f1dec164b5 util.iterators: Add sorted_pairs() method
Matthew Wild <mwild1@gmail.com>
parents: 8800
diff changeset
   188
			return key, t[key];
f6f1dec164b5 util.iterators: Add sorted_pairs() method
Matthew Wild <mwild1@gmail.com>
parents: 8800
diff changeset
   189
		end
f6f1dec164b5 util.iterators: Add sorted_pairs() method
Matthew Wild <mwild1@gmail.com>
parents: 8800
diff changeset
   190
	end;
f6f1dec164b5 util.iterators: Add sorted_pairs() method
Matthew Wild <mwild1@gmail.com>
parents: 8800
diff changeset
   191
end
f6f1dec164b5 util.iterators: Add sorted_pairs() method
Matthew Wild <mwild1@gmail.com>
parents: 8800
diff changeset
   192
3540
bc139431830b Monster whitespace commit (beware the whitespace monster).
Waqas Hussain <waqas20@gmail.com>
parents: 3392
diff changeset
   193
-- 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
   194
-- and build a table
4545
c9b91ddc9c11 util.iterators: Make a standard library (no longer injects into global namespace)
Matthew Wild <mwild1@gmail.com>
parents: 4441
diff changeset
   195
function it.to_table(f, s, var)
4441
a01b7207cb37 util.iterators: it2table: Fix variable name
Matthew Wild <mwild1@gmail.com>
parents: 4386
diff changeset
   196
	local t, var2 = {};
919
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   197
	while true do
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   198
		var, var2 = f(s, var);
7354
11434c46b7b7 util.iterators: Normalize indentation
Kim Alvefur <zash@zash.se>
parents: 7312
diff changeset
   199
		if var == nil then break; end
919
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   200
		t[var] = var2;
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   201
	end
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   202
	return t;
75b8afb79143 util.iterators: New iterators library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   203
end
4386
ce769240f8ec util.iterators: Add range(from, to)
Matthew Wild <mwild1@gmail.com>
parents: 3540
diff changeset
   204
8800
7b621a4a2e8d util.iterators: Add join() method and tests
Matthew Wild <mwild1@gmail.com>
parents: 8392
diff changeset
   205
local function _join_iter(j_s, j_var)
7b621a4a2e8d util.iterators: Add join() method and tests
Matthew Wild <mwild1@gmail.com>
parents: 8392
diff changeset
   206
	local iterators, current_idx = j_s[1], j_s[2];
7b621a4a2e8d util.iterators: Add join() method and tests
Matthew Wild <mwild1@gmail.com>
parents: 8392
diff changeset
   207
	local f, s, var = unpack(iterators[current_idx], 1, 3);
7b621a4a2e8d util.iterators: Add join() method and tests
Matthew Wild <mwild1@gmail.com>
parents: 8392
diff changeset
   208
	if j_var ~= nil then
7b621a4a2e8d util.iterators: Add join() method and tests
Matthew Wild <mwild1@gmail.com>
parents: 8392
diff changeset
   209
		var = j_var;
7b621a4a2e8d util.iterators: Add join() method and tests
Matthew Wild <mwild1@gmail.com>
parents: 8392
diff changeset
   210
	end
7b621a4a2e8d util.iterators: Add join() method and tests
Matthew Wild <mwild1@gmail.com>
parents: 8392
diff changeset
   211
	local ret = pack(f(s, var));
7b621a4a2e8d util.iterators: Add join() method and tests
Matthew Wild <mwild1@gmail.com>
parents: 8392
diff changeset
   212
	local var1 = ret[1];
7b621a4a2e8d util.iterators: Add join() method and tests
Matthew Wild <mwild1@gmail.com>
parents: 8392
diff changeset
   213
	if var1 == nil then
7b621a4a2e8d util.iterators: Add join() method and tests
Matthew Wild <mwild1@gmail.com>
parents: 8392
diff changeset
   214
		-- End of this iterator, advance to next
7b621a4a2e8d util.iterators: Add join() method and tests
Matthew Wild <mwild1@gmail.com>
parents: 8392
diff changeset
   215
		if current_idx == #iterators then
7b621a4a2e8d util.iterators: Add join() method and tests
Matthew Wild <mwild1@gmail.com>
parents: 8392
diff changeset
   216
			-- No more iterators, return nil
7b621a4a2e8d util.iterators: Add join() method and tests
Matthew Wild <mwild1@gmail.com>
parents: 8392
diff changeset
   217
			return;
7b621a4a2e8d util.iterators: Add join() method and tests
Matthew Wild <mwild1@gmail.com>
parents: 8392
diff changeset
   218
		end
7b621a4a2e8d util.iterators: Add join() method and tests
Matthew Wild <mwild1@gmail.com>
parents: 8392
diff changeset
   219
		j_s[2] = current_idx + 1;
7b621a4a2e8d util.iterators: Add join() method and tests
Matthew Wild <mwild1@gmail.com>
parents: 8392
diff changeset
   220
		return _join_iter(j_s);
7b621a4a2e8d util.iterators: Add join() method and tests
Matthew Wild <mwild1@gmail.com>
parents: 8392
diff changeset
   221
	end
7b621a4a2e8d util.iterators: Add join() method and tests
Matthew Wild <mwild1@gmail.com>
parents: 8392
diff changeset
   222
	return unpack(ret, 1, ret.n);
7b621a4a2e8d util.iterators: Add join() method and tests
Matthew Wild <mwild1@gmail.com>
parents: 8392
diff changeset
   223
end
7b621a4a2e8d util.iterators: Add join() method and tests
Matthew Wild <mwild1@gmail.com>
parents: 8392
diff changeset
   224
local join_methods = {};
7b621a4a2e8d util.iterators: Add join() method and tests
Matthew Wild <mwild1@gmail.com>
parents: 8392
diff changeset
   225
local join_mt = {
7b621a4a2e8d util.iterators: Add join() method and tests
Matthew Wild <mwild1@gmail.com>
parents: 8392
diff changeset
   226
	__index = join_methods;
7b621a4a2e8d util.iterators: Add join() method and tests
Matthew Wild <mwild1@gmail.com>
parents: 8392
diff changeset
   227
	__call = function (t, s, var) --luacheck: ignore 212/t
7b621a4a2e8d util.iterators: Add join() method and tests
Matthew Wild <mwild1@gmail.com>
parents: 8392
diff changeset
   228
		return _join_iter(s, var);
7b621a4a2e8d util.iterators: Add join() method and tests
Matthew Wild <mwild1@gmail.com>
parents: 8392
diff changeset
   229
	end;
7b621a4a2e8d util.iterators: Add join() method and tests
Matthew Wild <mwild1@gmail.com>
parents: 8392
diff changeset
   230
};
7b621a4a2e8d util.iterators: Add join() method and tests
Matthew Wild <mwild1@gmail.com>
parents: 8392
diff changeset
   231
7b621a4a2e8d util.iterators: Add join() method and tests
Matthew Wild <mwild1@gmail.com>
parents: 8392
diff changeset
   232
function join_methods:append(f, s, var)
7b621a4a2e8d util.iterators: Add join() method and tests
Matthew Wild <mwild1@gmail.com>
parents: 8392
diff changeset
   233
	table.insert(self, { f, s, var });
7b621a4a2e8d util.iterators: Add join() method and tests
Matthew Wild <mwild1@gmail.com>
parents: 8392
diff changeset
   234
	return self, { self, 1 };
7b621a4a2e8d util.iterators: Add join() method and tests
Matthew Wild <mwild1@gmail.com>
parents: 8392
diff changeset
   235
end
7b621a4a2e8d util.iterators: Add join() method and tests
Matthew Wild <mwild1@gmail.com>
parents: 8392
diff changeset
   236
7b621a4a2e8d util.iterators: Add join() method and tests
Matthew Wild <mwild1@gmail.com>
parents: 8392
diff changeset
   237
function join_methods:prepend(f, s, var)
7b621a4a2e8d util.iterators: Add join() method and tests
Matthew Wild <mwild1@gmail.com>
parents: 8392
diff changeset
   238
	table.insert(self, { f, s, var }, 1);
7b621a4a2e8d util.iterators: Add join() method and tests
Matthew Wild <mwild1@gmail.com>
parents: 8392
diff changeset
   239
	return self, { self, 1 };
7b621a4a2e8d util.iterators: Add join() method and tests
Matthew Wild <mwild1@gmail.com>
parents: 8392
diff changeset
   240
end
7b621a4a2e8d util.iterators: Add join() method and tests
Matthew Wild <mwild1@gmail.com>
parents: 8392
diff changeset
   241
7b621a4a2e8d util.iterators: Add join() method and tests
Matthew Wild <mwild1@gmail.com>
parents: 8392
diff changeset
   242
function it.join(f, s, var)
12748
e894677359e5 util.iterators: join: Work even with only a single iterator in the chain
Matthew Wild <mwild1@gmail.com>
parents: 12594
diff changeset
   243
	local t = setmetatable({ {f, s, var} }, join_mt);
e894677359e5 util.iterators: join: Work even with only a single iterator in the chain
Matthew Wild <mwild1@gmail.com>
parents: 12594
diff changeset
   244
	return t, { t, 1 };
8800
7b621a4a2e8d util.iterators: Add join() method and tests
Matthew Wild <mwild1@gmail.com>
parents: 8392
diff changeset
   245
end
7b621a4a2e8d util.iterators: Add join() method and tests
Matthew Wild <mwild1@gmail.com>
parents: 8392
diff changeset
   246
4545
c9b91ddc9c11 util.iterators: Make a standard library (no longer injects into global namespace)
Matthew Wild <mwild1@gmail.com>
parents: 4441
diff changeset
   247
return it;