util/array.lua
author Kim Alvefur <zash@zash.se>
Sat, 22 Jul 2023 16:31:05 +0200
branch0.12
changeset 13251 1bb4aa803b32
parent 13142 0b0cefce6e42
child 13252 db433ed3135c
permissions -rw-r--r--
util.array: Fix new() library function Backport of ffe4adbd2af9 since new was added in the 0.12 branch
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: 1373
diff changeset
     1
-- Prosody IM
2923
b7049746bd29 Update copyright headers for 2010
Matthew Wild <mwild1@gmail.com>
parents: 1934
diff changeset
     2
-- Copyright (C) 2008-2010 Matthew Wild
b7049746bd29 Update copyright headers for 2010
Matthew Wild <mwild1@gmail.com>
parents: 1934
diff changeset
     3
-- Copyright (C) 2008-2010 Waqas Hussain
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 5564
diff changeset
     4
--
1522
569d58d21612 Add copyright header to those files missing one
Matthew Wild <mwild1@gmail.com>
parents: 1373
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: 1373
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: 1373
diff changeset
     7
--
569d58d21612 Add copyright header to those files missing one
Matthew Wild <mwild1@gmail.com>
parents: 1373
diff changeset
     8
3540
bc139431830b Monster whitespace commit (beware the whitespace monster).
Waqas Hussain <waqas20@gmail.com>
parents: 2923
diff changeset
     9
local t_insert, t_sort, t_remove, t_concat
bc139431830b Monster whitespace commit (beware the whitespace monster).
Waqas Hussain <waqas20@gmail.com>
parents: 2923
diff changeset
    10
    = table.insert, table.sort, table.remove, table.concat;
918
967edf874df7 util.array: New array library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    11
4449
ca74d8ed1a15 util.array: Avoid globals.
Waqas Hussain <waqas20@gmail.com>
parents: 4448
diff changeset
    12
local setmetatable = setmetatable;
10596
9918b4b0cd58 util.array: Fix equality metamethod in Lua 5.3
Kim Alvefur <zash@zash.se>
parents: 9532
diff changeset
    13
local getmetatable = getmetatable;
4449
ca74d8ed1a15 util.array: Avoid globals.
Waqas Hussain <waqas20@gmail.com>
parents: 4448
diff changeset
    14
local math_random = math.random;
5857
8613888d0f9e util.array: Improve array:reverse() and make it work as both method and non-mutating function
Kim Alvefur <zash@zash.se>
parents: 5776
diff changeset
    15
local math_floor = math.floor;
4449
ca74d8ed1a15 util.array: Avoid globals.
Waqas Hussain <waqas20@gmail.com>
parents: 4448
diff changeset
    16
local pairs, ipairs = pairs, ipairs;
ca74d8ed1a15 util.array: Avoid globals.
Waqas Hussain <waqas20@gmail.com>
parents: 4448
diff changeset
    17
local tostring = tostring;
6420
060b63a27e9b util.array: Add type() local
Kim Alvefur <zash@zash.se>
parents: 5857
diff changeset
    18
local type = type;
4449
ca74d8ed1a15 util.array: Avoid globals.
Waqas Hussain <waqas20@gmail.com>
parents: 4448
diff changeset
    19
1905
e3e0a17e0b33 util.array: Per-array methods now always mutate the array, array.* return a mutated copy, and most methods (e.g. sort) now return the array
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
    20
local array = {};
e3e0a17e0b33 util.array: Per-array methods now always mutate the array, array.* return a mutated copy, and most methods (e.g. sort) now return the array
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
    21
local array_base = {};
e3e0a17e0b33 util.array: Per-array methods now always mutate the array, array.* return a mutated copy, and most methods (e.g. sort) now return the array
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
    22
local array_methods = {};
9531
1af7cc3b9747 util.array: Break long line
Matthew Wild <mwild1@gmail.com>
parents: 9490
diff changeset
    23
local array_mt = {
1af7cc3b9747 util.array: Break long line
Matthew Wild <mwild1@gmail.com>
parents: 9490
diff changeset
    24
	__index = array_methods;
1af7cc3b9747 util.array: Break long line
Matthew Wild <mwild1@gmail.com>
parents: 9490
diff changeset
    25
	__name = "array";
1af7cc3b9747 util.array: Break long line
Matthew Wild <mwild1@gmail.com>
parents: 9490
diff changeset
    26
	__tostring = function (self) return "{"..self:concat(", ").."}"; end;
1af7cc3b9747 util.array: Break long line
Matthew Wild <mwild1@gmail.com>
parents: 9490
diff changeset
    27
};
1905
e3e0a17e0b33 util.array: Per-array methods now always mutate the array, array.* return a mutated copy, and most methods (e.g. sort) now return the array
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
    28
9490
4e38121a349d util.array: Add freeze metamethod
Kim Alvefur <zash@zash.se>
parents: 8524
diff changeset
    29
function array_mt:__freeze() return self; end
4e38121a349d util.array: Add freeze metamethod
Kim Alvefur <zash@zash.se>
parents: 8524
diff changeset
    30
5085
cbc7eb5cfa8c util.array: Accept an iterator to the array constructor
Matthew Wild <mwild1@gmail.com>
parents: 4449
diff changeset
    31
local function new_array(self, t, _s, _var)
cbc7eb5cfa8c util.array: Accept an iterator to the array constructor
Matthew Wild <mwild1@gmail.com>
parents: 4449
diff changeset
    32
	if type(t) == "function" then -- Assume iterator
cbc7eb5cfa8c util.array: Accept an iterator to the array constructor
Matthew Wild <mwild1@gmail.com>
parents: 4449
diff changeset
    33
		t = self.collect(t, _s, _var);
cbc7eb5cfa8c util.array: Accept an iterator to the array constructor
Matthew Wild <mwild1@gmail.com>
parents: 4449
diff changeset
    34
	end
918
967edf874df7 util.array: New array library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    35
	return setmetatable(t or {}, array_mt);
967edf874df7 util.array: New array library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    36
end
967edf874df7 util.array: New array library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    37
13251
1bb4aa803b32 util.array: Fix new() library function
Kim Alvefur <zash@zash.se>
parents: 13142
diff changeset
    38
function array.new(t)
1bb4aa803b32 util.array: Fix new() library function
Kim Alvefur <zash@zash.se>
parents: 13142
diff changeset
    39
	return setmetatable(t or {}, array_mt);
1bb4aa803b32 util.array: Fix new() library function
Kim Alvefur <zash@zash.se>
parents: 13142
diff changeset
    40
end
13142
0b0cefce6e42 util.array: Expose new() on module table
Kim Alvefur <zash@zash.se>
parents: 11791
diff changeset
    41
1373
120275376bbb util.array: Add support for + operator to create a new array from two arrays joined
Matthew Wild <mwild1@gmail.com>
parents: 1372
diff changeset
    42
function array_mt.__add(a1, a2)
120275376bbb util.array: Add support for + operator to create a new array from two arrays joined
Matthew Wild <mwild1@gmail.com>
parents: 1372
diff changeset
    43
	local res = new_array();
120275376bbb util.array: Add support for + operator to create a new array from two arrays joined
Matthew Wild <mwild1@gmail.com>
parents: 1372
diff changeset
    44
	return res:append(a1):append(a2);
120275376bbb util.array: Add support for + operator to create a new array from two arrays joined
Matthew Wild <mwild1@gmail.com>
parents: 1372
diff changeset
    45
end
120275376bbb util.array: Add support for + operator to create a new array from two arrays joined
Matthew Wild <mwild1@gmail.com>
parents: 1372
diff changeset
    46
7979
2a7ef5fcaa77 util.array: Add O(n) equality check metamethod
Kim Alvefur <zash@zash.se>
parents: 7703
diff changeset
    47
function array_mt.__eq(a, b)
10596
9918b4b0cd58 util.array: Fix equality metamethod in Lua 5.3
Kim Alvefur <zash@zash.se>
parents: 9532
diff changeset
    48
	if getmetatable(a) ~= array_mt or getmetatable(b) ~= array_mt then
9918b4b0cd58 util.array: Fix equality metamethod in Lua 5.3
Kim Alvefur <zash@zash.se>
parents: 9532
diff changeset
    49
		-- Lua 5.3+ calls this if both operands are tables, even if metatables differ
9918b4b0cd58 util.array: Fix equality metamethod in Lua 5.3
Kim Alvefur <zash@zash.se>
parents: 9532
diff changeset
    50
		return false;
9918b4b0cd58 util.array: Fix equality metamethod in Lua 5.3
Kim Alvefur <zash@zash.se>
parents: 9532
diff changeset
    51
	end
7979
2a7ef5fcaa77 util.array: Add O(n) equality check metamethod
Kim Alvefur <zash@zash.se>
parents: 7703
diff changeset
    52
	if #a == #b then
2a7ef5fcaa77 util.array: Add O(n) equality check metamethod
Kim Alvefur <zash@zash.se>
parents: 7703
diff changeset
    53
		for i = 1, #a do
2a7ef5fcaa77 util.array: Add O(n) equality check metamethod
Kim Alvefur <zash@zash.se>
parents: 7703
diff changeset
    54
			if a[i] ~= b[i] then
2a7ef5fcaa77 util.array: Add O(n) equality check metamethod
Kim Alvefur <zash@zash.se>
parents: 7703
diff changeset
    55
				return false;
2a7ef5fcaa77 util.array: Add O(n) equality check metamethod
Kim Alvefur <zash@zash.se>
parents: 7703
diff changeset
    56
			end
2a7ef5fcaa77 util.array: Add O(n) equality check metamethod
Kim Alvefur <zash@zash.se>
parents: 7703
diff changeset
    57
		end
2a7ef5fcaa77 util.array: Add O(n) equality check metamethod
Kim Alvefur <zash@zash.se>
parents: 7703
diff changeset
    58
	else
2a7ef5fcaa77 util.array: Add O(n) equality check metamethod
Kim Alvefur <zash@zash.se>
parents: 7703
diff changeset
    59
		return false;
2a7ef5fcaa77 util.array: Add O(n) equality check metamethod
Kim Alvefur <zash@zash.se>
parents: 7703
diff changeset
    60
	end
2a7ef5fcaa77 util.array: Add O(n) equality check metamethod
Kim Alvefur <zash@zash.se>
parents: 7703
diff changeset
    61
	return true;
2a7ef5fcaa77 util.array: Add O(n) equality check metamethod
Kim Alvefur <zash@zash.se>
parents: 7703
diff changeset
    62
end
2a7ef5fcaa77 util.array: Add O(n) equality check metamethod
Kim Alvefur <zash@zash.se>
parents: 7703
diff changeset
    63
9532
6a1e7723208b util.array: Add __div for parity with util.set
Matthew Wild <mwild1@gmail.com>
parents: 9531
diff changeset
    64
function array_mt.__div(a1, func)
6a1e7723208b util.array: Add __div for parity with util.set
Matthew Wild <mwild1@gmail.com>
parents: 9531
diff changeset
    65
	local a2 = new_array();
6a1e7723208b util.array: Add __div for parity with util.set
Matthew Wild <mwild1@gmail.com>
parents: 9531
diff changeset
    66
	local o = 0;
6a1e7723208b util.array: Add __div for parity with util.set
Matthew Wild <mwild1@gmail.com>
parents: 9531
diff changeset
    67
	for i = 1, #a1 do
6a1e7723208b util.array: Add __div for parity with util.set
Matthew Wild <mwild1@gmail.com>
parents: 9531
diff changeset
    68
		local new_value = func(a1[i]);
6a1e7723208b util.array: Add __div for parity with util.set
Matthew Wild <mwild1@gmail.com>
parents: 9531
diff changeset
    69
		if new_value ~= nil then
6a1e7723208b util.array: Add __div for parity with util.set
Matthew Wild <mwild1@gmail.com>
parents: 9531
diff changeset
    70
			o = o + 1;
6a1e7723208b util.array: Add __div for parity with util.set
Matthew Wild <mwild1@gmail.com>
parents: 9531
diff changeset
    71
			a2[o] = new_value;
6a1e7723208b util.array: Add __div for parity with util.set
Matthew Wild <mwild1@gmail.com>
parents: 9531
diff changeset
    72
		end
6a1e7723208b util.array: Add __div for parity with util.set
Matthew Wild <mwild1@gmail.com>
parents: 9531
diff changeset
    73
	end
6a1e7723208b util.array: Add __div for parity with util.set
Matthew Wild <mwild1@gmail.com>
parents: 9531
diff changeset
    74
	return a2;
6a1e7723208b util.array: Add __div for parity with util.set
Matthew Wild <mwild1@gmail.com>
parents: 9531
diff changeset
    75
end
6a1e7723208b util.array: Add __div for parity with util.set
Matthew Wild <mwild1@gmail.com>
parents: 9531
diff changeset
    76
920
e302cbc9d036 util.array: Expose array.* functions, to be used for unwrapped arrays
Matthew Wild <mwild1@gmail.com>
parents: 918
diff changeset
    77
setmetatable(array, { __call = new_array });
e302cbc9d036 util.array: Expose array.* functions, to be used for unwrapped arrays
Matthew Wild <mwild1@gmail.com>
parents: 918
diff changeset
    78
4440
c60ed6732b34 util.array: Expand some of the more basic methods to act more sensibly than their names suggested
Matthew Wild <mwild1@gmail.com>
parents: 4439
diff changeset
    79
-- Read-only methods
c60ed6732b34 util.array: Expand some of the more basic methods to act more sensibly than their names suggested
Matthew Wild <mwild1@gmail.com>
parents: 4439
diff changeset
    80
function array_methods:random()
7022
abcd5ec3ee41 util.array: Fix minory style issues
Kim Alvefur <zash@zash.se>
parents: 6780
diff changeset
    81
	return self[math_random(1, #self)];
4440
c60ed6732b34 util.array: Expand some of the more basic methods to act more sensibly than their names suggested
Matthew Wild <mwild1@gmail.com>
parents: 4439
diff changeset
    82
end
c60ed6732b34 util.array: Expand some of the more basic methods to act more sensibly than their names suggested
Matthew Wild <mwild1@gmail.com>
parents: 4439
diff changeset
    83
9532
6a1e7723208b util.array: Add __div for parity with util.set
Matthew Wild <mwild1@gmail.com>
parents: 9531
diff changeset
    84
-- Return a random value excluding the one at idx
6a1e7723208b util.array: Add __div for parity with util.set
Matthew Wild <mwild1@gmail.com>
parents: 9531
diff changeset
    85
function array_methods:random_other(idx)
6a1e7723208b util.array: Add __div for parity with util.set
Matthew Wild <mwild1@gmail.com>
parents: 9531
diff changeset
    86
	local max = #self;
6a1e7723208b util.array: Add __div for parity with util.set
Matthew Wild <mwild1@gmail.com>
parents: 9531
diff changeset
    87
	return self[((math.random(1, max-1)+(idx-1))%max)+1];
6a1e7723208b util.array: Add __div for parity with util.set
Matthew Wild <mwild1@gmail.com>
parents: 9531
diff changeset
    88
end
6a1e7723208b util.array: Add __div for parity with util.set
Matthew Wild <mwild1@gmail.com>
parents: 9531
diff changeset
    89
4440
c60ed6732b34 util.array: Expand some of the more basic methods to act more sensibly than their names suggested
Matthew Wild <mwild1@gmail.com>
parents: 4439
diff changeset
    90
-- These methods can be called two ways:
c60ed6732b34 util.array: Expand some of the more basic methods to act more sensibly than their names suggested
Matthew Wild <mwild1@gmail.com>
parents: 4439
diff changeset
    91
--   array.method(existing_array, [params [, ...]]) -- Create new array for result
c60ed6732b34 util.array: Expand some of the more basic methods to act more sensibly than their names suggested
Matthew Wild <mwild1@gmail.com>
parents: 4439
diff changeset
    92
--   existing_array:method([params, ...]) -- Transform existing array into result
c60ed6732b34 util.array: Expand some of the more basic methods to act more sensibly than their names suggested
Matthew Wild <mwild1@gmail.com>
parents: 4439
diff changeset
    93
--
1905
e3e0a17e0b33 util.array: Per-array methods now always mutate the array, array.* return a mutated copy, and most methods (e.g. sort) now return the array
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
    94
function array_base.map(outa, ina, func)
7022
abcd5ec3ee41 util.array: Fix minory style issues
Kim Alvefur <zash@zash.se>
parents: 6780
diff changeset
    95
	for k, v in ipairs(ina) do
1905
e3e0a17e0b33 util.array: Per-array methods now always mutate the array, array.* return a mutated copy, and most methods (e.g. sort) now return the array
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
    96
		outa[k] = func(v);
918
967edf874df7 util.array: New array library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    97
	end
1905
e3e0a17e0b33 util.array: Per-array methods now always mutate the array, array.* return a mutated copy, and most methods (e.g. sort) now return the array
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
    98
	return outa;
918
967edf874df7 util.array: New array library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    99
end
967edf874df7 util.array: New array library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   100
1905
e3e0a17e0b33 util.array: Per-array methods now always mutate the array, array.* return a mutated copy, and most methods (e.g. sort) now return the array
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
   101
function array_base.filter(outa, ina, func)
1915
e9d5406caf8c util.array: Fix for array:filter() (in-place filtering)
Matthew Wild <mwild1@gmail.com>
parents: 1905
diff changeset
   102
	local inplace, start_length = ina == outa, #ina;
e9d5406caf8c util.array: Fix for array:filter() (in-place filtering)
Matthew Wild <mwild1@gmail.com>
parents: 1905
diff changeset
   103
	local write = 1;
7022
abcd5ec3ee41 util.array: Fix minory style issues
Kim Alvefur <zash@zash.se>
parents: 6780
diff changeset
   104
	for read = 1, start_length do
1915
e9d5406caf8c util.array: Fix for array:filter() (in-place filtering)
Matthew Wild <mwild1@gmail.com>
parents: 1905
diff changeset
   105
		local v = ina[read];
918
967edf874df7 util.array: New array library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   106
		if func(v) then
1915
e9d5406caf8c util.array: Fix for array:filter() (in-place filtering)
Matthew Wild <mwild1@gmail.com>
parents: 1905
diff changeset
   107
			outa[write] = v;
e9d5406caf8c util.array: Fix for array:filter() (in-place filtering)
Matthew Wild <mwild1@gmail.com>
parents: 1905
diff changeset
   108
			write = write + 1;
918
967edf874df7 util.array: New array library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   109
		end
967edf874df7 util.array: New array library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   110
	end
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 5564
diff changeset
   111
1922
d5fe0f9b377a util.array: Small logic fix for array:filter()
Matthew Wild <mwild1@gmail.com>
parents: 1915
diff changeset
   112
	if inplace and write <= start_length then
7022
abcd5ec3ee41 util.array: Fix minory style issues
Kim Alvefur <zash@zash.se>
parents: 6780
diff changeset
   113
		for i = write, start_length do
1915
e9d5406caf8c util.array: Fix for array:filter() (in-place filtering)
Matthew Wild <mwild1@gmail.com>
parents: 1905
diff changeset
   114
			outa[i] = nil;
e9d5406caf8c util.array: Fix for array:filter() (in-place filtering)
Matthew Wild <mwild1@gmail.com>
parents: 1905
diff changeset
   115
		end
e9d5406caf8c util.array: Fix for array:filter() (in-place filtering)
Matthew Wild <mwild1@gmail.com>
parents: 1905
diff changeset
   116
	end
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 5564
diff changeset
   117
1905
e3e0a17e0b33 util.array: Per-array methods now always mutate the array, array.* return a mutated copy, and most methods (e.g. sort) now return the array
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
   118
	return outa;
918
967edf874df7 util.array: New array library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   119
end
967edf874df7 util.array: New array library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   120
11791
3ae6fa901a8b util.array: Add :slice() method + tests
Matthew Wild <mwild1@gmail.com>
parents: 10899
diff changeset
   121
function array_base.slice(outa, ina, i, j)
3ae6fa901a8b util.array: Add :slice() method + tests
Matthew Wild <mwild1@gmail.com>
parents: 10899
diff changeset
   122
	if j == nil then
3ae6fa901a8b util.array: Add :slice() method + tests
Matthew Wild <mwild1@gmail.com>
parents: 10899
diff changeset
   123
		j = -1;
3ae6fa901a8b util.array: Add :slice() method + tests
Matthew Wild <mwild1@gmail.com>
parents: 10899
diff changeset
   124
	end
3ae6fa901a8b util.array: Add :slice() method + tests
Matthew Wild <mwild1@gmail.com>
parents: 10899
diff changeset
   125
	if j < 0 then
3ae6fa901a8b util.array: Add :slice() method + tests
Matthew Wild <mwild1@gmail.com>
parents: 10899
diff changeset
   126
		j = #ina + (j+1);
3ae6fa901a8b util.array: Add :slice() method + tests
Matthew Wild <mwild1@gmail.com>
parents: 10899
diff changeset
   127
	end
3ae6fa901a8b util.array: Add :slice() method + tests
Matthew Wild <mwild1@gmail.com>
parents: 10899
diff changeset
   128
	if i < 0 then
3ae6fa901a8b util.array: Add :slice() method + tests
Matthew Wild <mwild1@gmail.com>
parents: 10899
diff changeset
   129
		i = #ina + (i+1);
3ae6fa901a8b util.array: Add :slice() method + tests
Matthew Wild <mwild1@gmail.com>
parents: 10899
diff changeset
   130
	end
3ae6fa901a8b util.array: Add :slice() method + tests
Matthew Wild <mwild1@gmail.com>
parents: 10899
diff changeset
   131
	if i < 1 then
3ae6fa901a8b util.array: Add :slice() method + tests
Matthew Wild <mwild1@gmail.com>
parents: 10899
diff changeset
   132
		i = 1;
3ae6fa901a8b util.array: Add :slice() method + tests
Matthew Wild <mwild1@gmail.com>
parents: 10899
diff changeset
   133
	end
3ae6fa901a8b util.array: Add :slice() method + tests
Matthew Wild <mwild1@gmail.com>
parents: 10899
diff changeset
   134
	if j > #ina then
3ae6fa901a8b util.array: Add :slice() method + tests
Matthew Wild <mwild1@gmail.com>
parents: 10899
diff changeset
   135
		j = #ina;
3ae6fa901a8b util.array: Add :slice() method + tests
Matthew Wild <mwild1@gmail.com>
parents: 10899
diff changeset
   136
	end
3ae6fa901a8b util.array: Add :slice() method + tests
Matthew Wild <mwild1@gmail.com>
parents: 10899
diff changeset
   137
	if i > j then
3ae6fa901a8b util.array: Add :slice() method + tests
Matthew Wild <mwild1@gmail.com>
parents: 10899
diff changeset
   138
		for idx = 1, #outa do
3ae6fa901a8b util.array: Add :slice() method + tests
Matthew Wild <mwild1@gmail.com>
parents: 10899
diff changeset
   139
			outa[idx] = nil;
3ae6fa901a8b util.array: Add :slice() method + tests
Matthew Wild <mwild1@gmail.com>
parents: 10899
diff changeset
   140
		end
3ae6fa901a8b util.array: Add :slice() method + tests
Matthew Wild <mwild1@gmail.com>
parents: 10899
diff changeset
   141
		return outa;
3ae6fa901a8b util.array: Add :slice() method + tests
Matthew Wild <mwild1@gmail.com>
parents: 10899
diff changeset
   142
	end
3ae6fa901a8b util.array: Add :slice() method + tests
Matthew Wild <mwild1@gmail.com>
parents: 10899
diff changeset
   143
3ae6fa901a8b util.array: Add :slice() method + tests
Matthew Wild <mwild1@gmail.com>
parents: 10899
diff changeset
   144
	for idx = 1, 1+j-i do
3ae6fa901a8b util.array: Add :slice() method + tests
Matthew Wild <mwild1@gmail.com>
parents: 10899
diff changeset
   145
		outa[idx] = ina[i+(idx-1)];
3ae6fa901a8b util.array: Add :slice() method + tests
Matthew Wild <mwild1@gmail.com>
parents: 10899
diff changeset
   146
	end
3ae6fa901a8b util.array: Add :slice() method + tests
Matthew Wild <mwild1@gmail.com>
parents: 10899
diff changeset
   147
	if ina == outa then
3ae6fa901a8b util.array: Add :slice() method + tests
Matthew Wild <mwild1@gmail.com>
parents: 10899
diff changeset
   148
		for idx = 2+j-i, #outa do
3ae6fa901a8b util.array: Add :slice() method + tests
Matthew Wild <mwild1@gmail.com>
parents: 10899
diff changeset
   149
			outa[idx] = nil;
3ae6fa901a8b util.array: Add :slice() method + tests
Matthew Wild <mwild1@gmail.com>
parents: 10899
diff changeset
   150
		end
3ae6fa901a8b util.array: Add :slice() method + tests
Matthew Wild <mwild1@gmail.com>
parents: 10899
diff changeset
   151
	end
3ae6fa901a8b util.array: Add :slice() method + tests
Matthew Wild <mwild1@gmail.com>
parents: 10899
diff changeset
   152
	return outa;
3ae6fa901a8b util.array: Add :slice() method + tests
Matthew Wild <mwild1@gmail.com>
parents: 10899
diff changeset
   153
end
3ae6fa901a8b util.array: Add :slice() method + tests
Matthew Wild <mwild1@gmail.com>
parents: 10899
diff changeset
   154
1905
e3e0a17e0b33 util.array: Per-array methods now always mutate the array, array.* return a mutated copy, and most methods (e.g. sort) now return the array
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
   155
function array_base.sort(outa, ina, ...)
e3e0a17e0b33 util.array: Per-array methods now always mutate the array, array.* return a mutated copy, and most methods (e.g. sort) now return the array
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
   156
	if ina ~= outa then
e3e0a17e0b33 util.array: Per-array methods now always mutate the array, array.* return a mutated copy, and most methods (e.g. sort) now return the array
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
   157
		outa:append(ina);
e3e0a17e0b33 util.array: Per-array methods now always mutate the array, array.* return a mutated copy, and most methods (e.g. sort) now return the array
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
   158
	end
e3e0a17e0b33 util.array: Per-array methods now always mutate the array, array.* return a mutated copy, and most methods (e.g. sort) now return the array
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
   159
	t_sort(outa, ...);
e3e0a17e0b33 util.array: Per-array methods now always mutate the array, array.* return a mutated copy, and most methods (e.g. sort) now return the array
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
   160
	return outa;
e3e0a17e0b33 util.array: Per-array methods now always mutate the array, array.* return a mutated copy, and most methods (e.g. sort) now return the array
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
   161
end
918
967edf874df7 util.array: New array library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   162
8020
ec7cab8e744d util.array: Add method for filtering out duplicate values
Kim Alvefur <zash@zash.se>
parents: 7979
diff changeset
   163
function array_base.unique(outa, ina)
ec7cab8e744d util.array: Add method for filtering out duplicate values
Kim Alvefur <zash@zash.se>
parents: 7979
diff changeset
   164
	local seen = {};
ec7cab8e744d util.array: Add method for filtering out duplicate values
Kim Alvefur <zash@zash.se>
parents: 7979
diff changeset
   165
	return array_base.filter(outa, ina, function (item)
ec7cab8e744d util.array: Add method for filtering out duplicate values
Kim Alvefur <zash@zash.se>
parents: 7979
diff changeset
   166
		if seen[item] then
ec7cab8e744d util.array: Add method for filtering out duplicate values
Kim Alvefur <zash@zash.se>
parents: 7979
diff changeset
   167
			return false;
ec7cab8e744d util.array: Add method for filtering out duplicate values
Kim Alvefur <zash@zash.se>
parents: 7979
diff changeset
   168
		else
ec7cab8e744d util.array: Add method for filtering out duplicate values
Kim Alvefur <zash@zash.se>
parents: 7979
diff changeset
   169
			seen[item] = true;
ec7cab8e744d util.array: Add method for filtering out duplicate values
Kim Alvefur <zash@zash.se>
parents: 7979
diff changeset
   170
			return true;
ec7cab8e744d util.array: Add method for filtering out duplicate values
Kim Alvefur <zash@zash.se>
parents: 7979
diff changeset
   171
		end
ec7cab8e744d util.array: Add method for filtering out duplicate values
Kim Alvefur <zash@zash.se>
parents: 7979
diff changeset
   172
	end);
ec7cab8e744d util.array: Add method for filtering out duplicate values
Kim Alvefur <zash@zash.se>
parents: 7979
diff changeset
   173
end
ec7cab8e744d util.array: Add method for filtering out duplicate values
Kim Alvefur <zash@zash.se>
parents: 7979
diff changeset
   174
10899
5777968301e8 util.array: pluck: Support default value to avoid holes
Matthew Wild <mwild1@gmail.com>
parents: 10596
diff changeset
   175
function array_base.pluck(outa, ina, key, default)
7022
abcd5ec3ee41 util.array: Fix minory style issues
Kim Alvefur <zash@zash.se>
parents: 6780
diff changeset
   176
	for i = 1, #ina do
10899
5777968301e8 util.array: pluck: Support default value to avoid holes
Matthew Wild <mwild1@gmail.com>
parents: 10596
diff changeset
   177
		local v = ina[i][key];
5777968301e8 util.array: pluck: Support default value to avoid holes
Matthew Wild <mwild1@gmail.com>
parents: 10596
diff changeset
   178
		if v == nil then
5777968301e8 util.array: pluck: Support default value to avoid holes
Matthew Wild <mwild1@gmail.com>
parents: 10596
diff changeset
   179
			v = default;
5777968301e8 util.array: pluck: Support default value to avoid holes
Matthew Wild <mwild1@gmail.com>
parents: 10596
diff changeset
   180
		end
5777968301e8 util.array: pluck: Support default value to avoid holes
Matthew Wild <mwild1@gmail.com>
parents: 10596
diff changeset
   181
		outa[i] = v;
4439
1c8d2c0d02db util.array: Add pluck() method to pick a given property from each item
Matthew Wild <mwild1@gmail.com>
parents: 4387
diff changeset
   182
	end
1c8d2c0d02db util.array: Add pluck() method to pick a given property from each item
Matthew Wild <mwild1@gmail.com>
parents: 4387
diff changeset
   183
	return outa;
1c8d2c0d02db util.array: Add pluck() method to pick a given property from each item
Matthew Wild <mwild1@gmail.com>
parents: 4387
diff changeset
   184
end
1c8d2c0d02db util.array: Add pluck() method to pick a given property from each item
Matthew Wild <mwild1@gmail.com>
parents: 4387
diff changeset
   185
5857
8613888d0f9e util.array: Improve array:reverse() and make it work as both method and non-mutating function
Kim Alvefur <zash@zash.se>
parents: 5776
diff changeset
   186
function array_base.reverse(outa, ina)
8613888d0f9e util.array: Improve array:reverse() and make it work as both method and non-mutating function
Kim Alvefur <zash@zash.se>
parents: 5776
diff changeset
   187
	local len = #ina;
8613888d0f9e util.array: Improve array:reverse() and make it work as both method and non-mutating function
Kim Alvefur <zash@zash.se>
parents: 5776
diff changeset
   188
	if ina == outa then
8613888d0f9e util.array: Improve array:reverse() and make it work as both method and non-mutating function
Kim Alvefur <zash@zash.se>
parents: 5776
diff changeset
   189
		local middle = math_floor(len/2);
8613888d0f9e util.array: Improve array:reverse() and make it work as both method and non-mutating function
Kim Alvefur <zash@zash.se>
parents: 5776
diff changeset
   190
		len = len + 1;
8613888d0f9e util.array: Improve array:reverse() and make it work as both method and non-mutating function
Kim Alvefur <zash@zash.se>
parents: 5776
diff changeset
   191
		local o; -- opposite
8613888d0f9e util.array: Improve array:reverse() and make it work as both method and non-mutating function
Kim Alvefur <zash@zash.se>
parents: 5776
diff changeset
   192
		for i = 1, middle do
8613888d0f9e util.array: Improve array:reverse() and make it work as both method and non-mutating function
Kim Alvefur <zash@zash.se>
parents: 5776
diff changeset
   193
			o = len - i;
8613888d0f9e util.array: Improve array:reverse() and make it work as both method and non-mutating function
Kim Alvefur <zash@zash.se>
parents: 5776
diff changeset
   194
			outa[i], outa[o] = outa[o], outa[i];
8613888d0f9e util.array: Improve array:reverse() and make it work as both method and non-mutating function
Kim Alvefur <zash@zash.se>
parents: 5776
diff changeset
   195
		end
8613888d0f9e util.array: Improve array:reverse() and make it work as both method and non-mutating function
Kim Alvefur <zash@zash.se>
parents: 5776
diff changeset
   196
	else
8613888d0f9e util.array: Improve array:reverse() and make it work as both method and non-mutating function
Kim Alvefur <zash@zash.se>
parents: 5776
diff changeset
   197
		local off = len + 1;
8613888d0f9e util.array: Improve array:reverse() and make it work as both method and non-mutating function
Kim Alvefur <zash@zash.se>
parents: 5776
diff changeset
   198
		for i = 1, len do
8613888d0f9e util.array: Improve array:reverse() and make it work as both method and non-mutating function
Kim Alvefur <zash@zash.se>
parents: 5776
diff changeset
   199
			outa[i] = ina[off - i];
8613888d0f9e util.array: Improve array:reverse() and make it work as both method and non-mutating function
Kim Alvefur <zash@zash.se>
parents: 5776
diff changeset
   200
		end
8613888d0f9e util.array: Improve array:reverse() and make it work as both method and non-mutating function
Kim Alvefur <zash@zash.se>
parents: 5776
diff changeset
   201
	end
8613888d0f9e util.array: Improve array:reverse() and make it work as both method and non-mutating function
Kim Alvefur <zash@zash.se>
parents: 5776
diff changeset
   202
	return outa;
8613888d0f9e util.array: Improve array:reverse() and make it work as both method and non-mutating function
Kim Alvefur <zash@zash.se>
parents: 5776
diff changeset
   203
end
8613888d0f9e util.array: Improve array:reverse() and make it work as both method and non-mutating function
Kim Alvefur <zash@zash.se>
parents: 5776
diff changeset
   204
4440
c60ed6732b34 util.array: Expand some of the more basic methods to act more sensibly than their names suggested
Matthew Wild <mwild1@gmail.com>
parents: 4439
diff changeset
   205
--- These methods only mutate the array
7703
0d70410efdcf util.array: Remove unused arguments [luacheck]
Kim Alvefur <zash@zash.se>
parents: 7702
diff changeset
   206
function array_methods:shuffle()
918
967edf874df7 util.array: New array library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   207
	local len = #self;
7022
abcd5ec3ee41 util.array: Fix minory style issues
Kim Alvefur <zash@zash.se>
parents: 6780
diff changeset
   208
	for i = 1, #self do
abcd5ec3ee41 util.array: Fix minory style issues
Kim Alvefur <zash@zash.se>
parents: 6780
diff changeset
   209
		local r = math_random(i, len);
918
967edf874df7 util.array: New array library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   210
		self[i], self[r] = self[r], self[i];
967edf874df7 util.array: New array library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   211
	end
1372
3b13bb57002e util.array: Make array:reverse() and array:shuffle() return the array to allow chaining
Matthew Wild <mwild1@gmail.com>
parents: 1371
diff changeset
   212
	return self;
918
967edf874df7 util.array: New array library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   213
end
967edf874df7 util.array: New array library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   214
7702
9c40d0be2295 util.array: Rename arguments to avoid name clash [luacheck]
Kim Alvefur <zash@zash.se>
parents: 7023
diff changeset
   215
function array_methods:append(ina)
9c40d0be2295 util.array: Rename arguments to avoid name clash [luacheck]
Kim Alvefur <zash@zash.se>
parents: 7023
diff changeset
   216
	local len, len2 = #self, #ina;
7022
abcd5ec3ee41 util.array: Fix minory style issues
Kim Alvefur <zash@zash.se>
parents: 6780
diff changeset
   217
	for i = 1, len2 do
7702
9c40d0be2295 util.array: Rename arguments to avoid name clash [luacheck]
Kim Alvefur <zash@zash.se>
parents: 7023
diff changeset
   218
		self[len+i] = ina[i];
1371
9e45bdf55353 util.array: Add array:append() method, to append a new array to an existing one
Matthew Wild <mwild1@gmail.com>
parents: 1027
diff changeset
   219
	end
9e45bdf55353 util.array: Add array:append() method, to append a new array to an existing one
Matthew Wild <mwild1@gmail.com>
parents: 1027
diff changeset
   220
	return self;
9e45bdf55353 util.array: Add array:append() method, to append a new array to an existing one
Matthew Wild <mwild1@gmail.com>
parents: 1027
diff changeset
   221
end
9e45bdf55353 util.array: Add array:append() method, to append a new array to an existing one
Matthew Wild <mwild1@gmail.com>
parents: 1027
diff changeset
   222
4440
c60ed6732b34 util.array: Expand some of the more basic methods to act more sensibly than their names suggested
Matthew Wild <mwild1@gmail.com>
parents: 4439
diff changeset
   223
function array_methods:push(x)
4449
ca74d8ed1a15 util.array: Avoid globals.
Waqas Hussain <waqas20@gmail.com>
parents: 4448
diff changeset
   224
	t_insert(self, x);
4448
d745f4c28294 util.array: Make array:push() chainable.
Waqas Hussain <waqas20@gmail.com>
parents: 4440
diff changeset
   225
	return self;
4440
c60ed6732b34 util.array: Expand some of the more basic methods to act more sensibly than their names suggested
Matthew Wild <mwild1@gmail.com>
parents: 4439
diff changeset
   226
end
c60ed6732b34 util.array: Expand some of the more basic methods to act more sensibly than their names suggested
Matthew Wild <mwild1@gmail.com>
parents: 4439
diff changeset
   227
7023
6ab9c691c4c6 util.array: Just use table.remove as array:pop()
Kim Alvefur <zash@zash.se>
parents: 7022
diff changeset
   228
array_methods.pop = t_remove;
4440
c60ed6732b34 util.array: Expand some of the more basic methods to act more sensibly than their names suggested
Matthew Wild <mwild1@gmail.com>
parents: 4439
diff changeset
   229
c60ed6732b34 util.array: Expand some of the more basic methods to act more sensibly than their names suggested
Matthew Wild <mwild1@gmail.com>
parents: 4439
diff changeset
   230
function array_methods:concat(sep)
4449
ca74d8ed1a15 util.array: Avoid globals.
Waqas Hussain <waqas20@gmail.com>
parents: 4448
diff changeset
   231
	return t_concat(array.map(self, tostring), sep);
4440
c60ed6732b34 util.array: Expand some of the more basic methods to act more sensibly than their names suggested
Matthew Wild <mwild1@gmail.com>
parents: 4439
diff changeset
   232
end
c60ed6732b34 util.array: Expand some of the more basic methods to act more sensibly than their names suggested
Matthew Wild <mwild1@gmail.com>
parents: 4439
diff changeset
   233
c60ed6732b34 util.array: Expand some of the more basic methods to act more sensibly than their names suggested
Matthew Wild <mwild1@gmail.com>
parents: 4439
diff changeset
   234
function array_methods:length()
c60ed6732b34 util.array: Expand some of the more basic methods to act more sensibly than their names suggested
Matthew Wild <mwild1@gmail.com>
parents: 4439
diff changeset
   235
	return #self;
c60ed6732b34 util.array: Expand some of the more basic methods to act more sensibly than their names suggested
Matthew Wild <mwild1@gmail.com>
parents: 4439
diff changeset
   236
end
1905
e3e0a17e0b33 util.array: Per-array methods now always mutate the array, array.* return a mutated copy, and most methods (e.g. sort) now return the array
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
   237
e3e0a17e0b33 util.array: Per-array methods now always mutate the array, array.* return a mutated copy, and most methods (e.g. sort) now return the array
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
   238
--- These methods always create a new array
1027
fe2e3d3dba6a util.array: Add array.collect() to collect results from iterators into an array, and use module() to correctly set the module name
Matthew Wild <mwild1@gmail.com>
parents: 922
diff changeset
   239
function array.collect(f, s, var)
4387
06161b0b83f2 util.array: Fix array.collect() for iterators that expect initial value of var to be preserved
Matthew Wild <mwild1@gmail.com>
parents: 3540
diff changeset
   240
	local t = {};
1027
fe2e3d3dba6a util.array: Add array.collect() to collect results from iterators into an array, and use module() to correctly set the module name
Matthew Wild <mwild1@gmail.com>
parents: 922
diff changeset
   241
	while true do
fe2e3d3dba6a util.array: Add array.collect() to collect results from iterators into an array, and use module() to correctly set the module name
Matthew Wild <mwild1@gmail.com>
parents: 922
diff changeset
   242
		var = f(s, var);
7022
abcd5ec3ee41 util.array: Fix minory style issues
Kim Alvefur <zash@zash.se>
parents: 6780
diff changeset
   243
		if var == nil then break; end
4449
ca74d8ed1a15 util.array: Avoid globals.
Waqas Hussain <waqas20@gmail.com>
parents: 4448
diff changeset
   244
		t_insert(t, var);
1027
fe2e3d3dba6a util.array: Add array.collect() to collect results from iterators into an array, and use module() to correctly set the module name
Matthew Wild <mwild1@gmail.com>
parents: 922
diff changeset
   245
	end
fe2e3d3dba6a util.array: Add array.collect() to collect results from iterators into an array, and use module() to correctly set the module name
Matthew Wild <mwild1@gmail.com>
parents: 922
diff changeset
   246
	return setmetatable(t, array_mt);
fe2e3d3dba6a util.array: Add array.collect() to collect results from iterators into an array, and use module() to correctly set the module name
Matthew Wild <mwild1@gmail.com>
parents: 922
diff changeset
   247
end
fe2e3d3dba6a util.array: Add array.collect() to collect results from iterators into an array, and use module() to correctly set the module name
Matthew Wild <mwild1@gmail.com>
parents: 922
diff changeset
   248
1905
e3e0a17e0b33 util.array: Per-array methods now always mutate the array, array.* return a mutated copy, and most methods (e.g. sort) now return the array
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
   249
---
e3e0a17e0b33 util.array: Per-array methods now always mutate the array, array.* return a mutated copy, and most methods (e.g. sort) now return the array
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
   250
e3e0a17e0b33 util.array: Per-array methods now always mutate the array, array.* return a mutated copy, and most methods (e.g. sort) now return the array
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
   251
-- Setup methods from array_base
e3e0a17e0b33 util.array: Per-array methods now always mutate the array, array.* return a mutated copy, and most methods (e.g. sort) now return the array
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
   252
for method, f in pairs(array_base) do
e3e0a17e0b33 util.array: Per-array methods now always mutate the array, array.* return a mutated copy, and most methods (e.g. sort) now return the array
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
   253
	local base_method = f;
e3e0a17e0b33 util.array: Per-array methods now always mutate the array, array.* return a mutated copy, and most methods (e.g. sort) now return the array
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
   254
	-- Setup global array method which makes new array
e3e0a17e0b33 util.array: Per-array methods now always mutate the array, array.* return a mutated copy, and most methods (e.g. sort) now return the array
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
   255
	array[method] = function (old_a, ...)
e3e0a17e0b33 util.array: Per-array methods now always mutate the array, array.* return a mutated copy, and most methods (e.g. sort) now return the array
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
   256
		local a = new_array();
e3e0a17e0b33 util.array: Per-array methods now always mutate the array, array.* return a mutated copy, and most methods (e.g. sort) now return the array
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
   257
		return base_method(a, old_a, ...);
e3e0a17e0b33 util.array: Per-array methods now always mutate the array, array.* return a mutated copy, and most methods (e.g. sort) now return the array
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
   258
	end
e3e0a17e0b33 util.array: Per-array methods now always mutate the array, array.* return a mutated copy, and most methods (e.g. sort) now return the array
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
   259
	-- Setup per-array (mutating) method
e3e0a17e0b33 util.array: Per-array methods now always mutate the array, array.* return a mutated copy, and most methods (e.g. sort) now return the array
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
   260
	array_methods[method] = function (self, ...)
e3e0a17e0b33 util.array: Per-array methods now always mutate the array, array.* return a mutated copy, and most methods (e.g. sort) now return the array
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
   261
		return base_method(self, self, ...);
e3e0a17e0b33 util.array: Per-array methods now always mutate the array, array.* return a mutated copy, and most methods (e.g. sort) now return the array
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
   262
	end
e3e0a17e0b33 util.array: Per-array methods now always mutate the array, array.* return a mutated copy, and most methods (e.g. sort) now return the array
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
   263
end
e3e0a17e0b33 util.array: Per-array methods now always mutate the array, array.* return a mutated copy, and most methods (e.g. sort) now return the array
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
   264
1027
fe2e3d3dba6a util.array: Add array.collect() to collect results from iterators into an array, and use module() to correctly set the module name
Matthew Wild <mwild1@gmail.com>
parents: 922
diff changeset
   265
return array;