util/iterators.lua
author Kim Alvefur <zash@zash.se>
Mon, 12 Dec 2022 07:03:31 +0100
branch0.11
changeset 12802 c4b1b5cbc20b
parent 9330 f6f1dec164b5
child 9692 eade1316728e
permissions -rw-r--r--
Tag 0.11.14
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;
7187
dedc6bf180e2 util.iterators: Localize unpack() in Lua 5.2 compatible way
Kim Alvefur <zash@zash.se>
parents: 5776
diff changeset
    14
local select, next = select, next;
8392
5d866eb8f18f util: Ignore some Lua 5.1 vs 5.2 compat things [luacheck]
Kim Alvefur <zash@zash.se>
parents: 7358
diff changeset
    15
local unpack = table.unpack or unpack; --luacheck: ignore 113 143
5d866eb8f18f util: Ignore some Lua 5.1 vs 5.2 compat things [luacheck]
Kim Alvefur <zash@zash.se>
parents: 7358
diff changeset
    16
local pack = table.pack or function (...) return { n = select("#", ...), ... }; end -- luacheck: ignore 143
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)
7b621a4a2e8d util.iterators: Add join() method and tests
Matthew Wild <mwild1@gmail.com>
parents: 8392
diff changeset
   243
	return setmetatable({ {f, s, var} }, join_mt);
7b621a4a2e8d util.iterators: Add join() method and tests
Matthew Wild <mwild1@gmail.com>
parents: 8392
diff changeset
   244
end
7b621a4a2e8d util.iterators: Add join() method and tests
Matthew Wild <mwild1@gmail.com>
parents: 8392
diff changeset
   245
4545
c9b91ddc9c11 util.iterators: Make a standard library (no longer injects into global namespace)
Matthew Wild <mwild1@gmail.com>
parents: 4441
diff changeset
   246
return it;