util/array.lua
author Kim Alvefur <zash@zash.se>
Tue, 22 Nov 2022 23:56:01 +0100
branch0.11
changeset 12801 be09ac8300a7
parent 9532 6a1e7723208b
child 10596 9918b4b0cd58
permissions -rw-r--r--
util.stanza: Allow U+7F Allowed by XML despite arguably being a control character. Drops the part of the range meant to rule out octets invalid in UTF-8 (\247 starts a 4-byte sequence), since UTF-8 correctness is validated by util.encodings.utf8.valid().
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;
ca74d8ed1a15 util.array: Avoid globals.
Waqas Hussain <waqas20@gmail.com>
parents: 4448
diff changeset
    13
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
    14
local math_floor = math.floor;
4449
ca74d8ed1a15 util.array: Avoid globals.
Waqas Hussain <waqas20@gmail.com>
parents: 4448
diff changeset
    15
local pairs, ipairs = pairs, ipairs;
ca74d8ed1a15 util.array: Avoid globals.
Waqas Hussain <waqas20@gmail.com>
parents: 4448
diff changeset
    16
local tostring = tostring;
6420
060b63a27e9b util.array: Add type() local
Kim Alvefur <zash@zash.se>
parents: 5857
diff changeset
    17
local type = type;
4449
ca74d8ed1a15 util.array: Avoid globals.
Waqas Hussain <waqas20@gmail.com>
parents: 4448
diff changeset
    18
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
    19
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
    20
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
    21
local array_methods = {};
9531
1af7cc3b9747 util.array: Break long line
Matthew Wild <mwild1@gmail.com>
parents: 9490
diff changeset
    22
local array_mt = {
1af7cc3b9747 util.array: Break long line
Matthew Wild <mwild1@gmail.com>
parents: 9490
diff changeset
    23
	__index = array_methods;
1af7cc3b9747 util.array: Break long line
Matthew Wild <mwild1@gmail.com>
parents: 9490
diff changeset
    24
	__name = "array";
1af7cc3b9747 util.array: Break long line
Matthew Wild <mwild1@gmail.com>
parents: 9490
diff changeset
    25
	__tostring = function (self) return "{"..self:concat(", ").."}"; end;
1af7cc3b9747 util.array: Break long line
Matthew Wild <mwild1@gmail.com>
parents: 9490
diff changeset
    26
};
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
    27
9490
4e38121a349d util.array: Add freeze metamethod
Kim Alvefur <zash@zash.se>
parents: 8524
diff changeset
    28
function array_mt:__freeze() return self; end
4e38121a349d util.array: Add freeze metamethod
Kim Alvefur <zash@zash.se>
parents: 8524
diff changeset
    29
5085
cbc7eb5cfa8c util.array: Accept an iterator to the array constructor
Matthew Wild <mwild1@gmail.com>
parents: 4449
diff changeset
    30
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
    31
	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
    32
		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
    33
	end
918
967edf874df7 util.array: New array library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    34
	return setmetatable(t or {}, array_mt);
967edf874df7 util.array: New array library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    35
end
967edf874df7 util.array: New array library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    36
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
    37
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
    38
	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
    39
	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
    40
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
    41
7979
2a7ef5fcaa77 util.array: Add O(n) equality check metamethod
Kim Alvefur <zash@zash.se>
parents: 7703
diff changeset
    42
function array_mt.__eq(a, b)
2a7ef5fcaa77 util.array: Add O(n) equality check metamethod
Kim Alvefur <zash@zash.se>
parents: 7703
diff changeset
    43
	if #a == #b then
2a7ef5fcaa77 util.array: Add O(n) equality check metamethod
Kim Alvefur <zash@zash.se>
parents: 7703
diff changeset
    44
		for i = 1, #a do
2a7ef5fcaa77 util.array: Add O(n) equality check metamethod
Kim Alvefur <zash@zash.se>
parents: 7703
diff changeset
    45
			if a[i] ~= b[i] then
2a7ef5fcaa77 util.array: Add O(n) equality check metamethod
Kim Alvefur <zash@zash.se>
parents: 7703
diff changeset
    46
				return false;
2a7ef5fcaa77 util.array: Add O(n) equality check metamethod
Kim Alvefur <zash@zash.se>
parents: 7703
diff changeset
    47
			end
2a7ef5fcaa77 util.array: Add O(n) equality check metamethod
Kim Alvefur <zash@zash.se>
parents: 7703
diff changeset
    48
		end
2a7ef5fcaa77 util.array: Add O(n) equality check metamethod
Kim Alvefur <zash@zash.se>
parents: 7703
diff changeset
    49
	else
2a7ef5fcaa77 util.array: Add O(n) equality check metamethod
Kim Alvefur <zash@zash.se>
parents: 7703
diff changeset
    50
		return false;
2a7ef5fcaa77 util.array: Add O(n) equality check metamethod
Kim Alvefur <zash@zash.se>
parents: 7703
diff changeset
    51
	end
2a7ef5fcaa77 util.array: Add O(n) equality check metamethod
Kim Alvefur <zash@zash.se>
parents: 7703
diff changeset
    52
	return true;
2a7ef5fcaa77 util.array: Add O(n) equality check metamethod
Kim Alvefur <zash@zash.se>
parents: 7703
diff changeset
    53
end
2a7ef5fcaa77 util.array: Add O(n) equality check metamethod
Kim Alvefur <zash@zash.se>
parents: 7703
diff changeset
    54
9532
6a1e7723208b util.array: Add __div for parity with util.set
Matthew Wild <mwild1@gmail.com>
parents: 9531
diff changeset
    55
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
    56
	local a2 = new_array();
6a1e7723208b util.array: Add __div for parity with util.set
Matthew Wild <mwild1@gmail.com>
parents: 9531
diff changeset
    57
	local o = 0;
6a1e7723208b util.array: Add __div for parity with util.set
Matthew Wild <mwild1@gmail.com>
parents: 9531
diff changeset
    58
	for i = 1, #a1 do
6a1e7723208b util.array: Add __div for parity with util.set
Matthew Wild <mwild1@gmail.com>
parents: 9531
diff changeset
    59
		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
    60
		if new_value ~= nil then
6a1e7723208b util.array: Add __div for parity with util.set
Matthew Wild <mwild1@gmail.com>
parents: 9531
diff changeset
    61
			o = o + 1;
6a1e7723208b util.array: Add __div for parity with util.set
Matthew Wild <mwild1@gmail.com>
parents: 9531
diff changeset
    62
			a2[o] = new_value;
6a1e7723208b util.array: Add __div for parity with util.set
Matthew Wild <mwild1@gmail.com>
parents: 9531
diff changeset
    63
		end
6a1e7723208b util.array: Add __div for parity with util.set
Matthew Wild <mwild1@gmail.com>
parents: 9531
diff changeset
    64
	end
6a1e7723208b util.array: Add __div for parity with util.set
Matthew Wild <mwild1@gmail.com>
parents: 9531
diff changeset
    65
	return a2;
6a1e7723208b util.array: Add __div for parity with util.set
Matthew Wild <mwild1@gmail.com>
parents: 9531
diff changeset
    66
end
6a1e7723208b util.array: Add __div for parity with util.set
Matthew Wild <mwild1@gmail.com>
parents: 9531
diff changeset
    67
920
e302cbc9d036 util.array: Expose array.* functions, to be used for unwrapped arrays
Matthew Wild <mwild1@gmail.com>
parents: 918
diff changeset
    68
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
    69
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
    70
-- 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
    71
function array_methods:random()
7022
abcd5ec3ee41 util.array: Fix minory style issues
Kim Alvefur <zash@zash.se>
parents: 6780
diff changeset
    72
	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
    73
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
    74
9532
6a1e7723208b util.array: Add __div for parity with util.set
Matthew Wild <mwild1@gmail.com>
parents: 9531
diff changeset
    75
-- 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
    76
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
    77
	local max = #self;
6a1e7723208b util.array: Add __div for parity with util.set
Matthew Wild <mwild1@gmail.com>
parents: 9531
diff changeset
    78
	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
    79
end
6a1e7723208b util.array: Add __div for parity with util.set
Matthew Wild <mwild1@gmail.com>
parents: 9531
diff changeset
    80
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
    81
-- 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
    82
--   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
    83
--   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
    84
--
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
    85
function array_base.map(outa, ina, func)
7022
abcd5ec3ee41 util.array: Fix minory style issues
Kim Alvefur <zash@zash.se>
parents: 6780
diff changeset
    86
	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
    87
		outa[k] = func(v);
918
967edf874df7 util.array: New array library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    88
	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
    89
	return outa;
918
967edf874df7 util.array: New array library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    90
end
967edf874df7 util.array: New array library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    91
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
    92
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
    93
	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
    94
	local write = 1;
7022
abcd5ec3ee41 util.array: Fix minory style issues
Kim Alvefur <zash@zash.se>
parents: 6780
diff changeset
    95
	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
    96
		local v = ina[read];
918
967edf874df7 util.array: New array library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    97
		if func(v) then
1915
e9d5406caf8c util.array: Fix for array:filter() (in-place filtering)
Matthew Wild <mwild1@gmail.com>
parents: 1905
diff changeset
    98
			outa[write] = v;
e9d5406caf8c util.array: Fix for array:filter() (in-place filtering)
Matthew Wild <mwild1@gmail.com>
parents: 1905
diff changeset
    99
			write = write + 1;
918
967edf874df7 util.array: New array library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   100
		end
967edf874df7 util.array: New array library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   101
	end
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 5564
diff changeset
   102
1922
d5fe0f9b377a util.array: Small logic fix for array:filter()
Matthew Wild <mwild1@gmail.com>
parents: 1915
diff changeset
   103
	if inplace and write <= start_length then
7022
abcd5ec3ee41 util.array: Fix minory style issues
Kim Alvefur <zash@zash.se>
parents: 6780
diff changeset
   104
		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
   105
			outa[i] = nil;
e9d5406caf8c util.array: Fix for array:filter() (in-place filtering)
Matthew Wild <mwild1@gmail.com>
parents: 1905
diff changeset
   106
		end
e9d5406caf8c util.array: Fix for array:filter() (in-place filtering)
Matthew Wild <mwild1@gmail.com>
parents: 1905
diff changeset
   107
	end
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 5564
diff changeset
   108
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
   109
	return outa;
918
967edf874df7 util.array: New array library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   110
end
967edf874df7 util.array: New array library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   111
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
   112
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
   113
	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
   114
		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
   115
	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
   116
	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
   117
	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
   118
end
918
967edf874df7 util.array: New array library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   119
8020
ec7cab8e744d util.array: Add method for filtering out duplicate values
Kim Alvefur <zash@zash.se>
parents: 7979
diff changeset
   120
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
   121
	local seen = {};
ec7cab8e744d util.array: Add method for filtering out duplicate values
Kim Alvefur <zash@zash.se>
parents: 7979
diff changeset
   122
	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
   123
		if seen[item] then
ec7cab8e744d util.array: Add method for filtering out duplicate values
Kim Alvefur <zash@zash.se>
parents: 7979
diff changeset
   124
			return false;
ec7cab8e744d util.array: Add method for filtering out duplicate values
Kim Alvefur <zash@zash.se>
parents: 7979
diff changeset
   125
		else
ec7cab8e744d util.array: Add method for filtering out duplicate values
Kim Alvefur <zash@zash.se>
parents: 7979
diff changeset
   126
			seen[item] = true;
ec7cab8e744d util.array: Add method for filtering out duplicate values
Kim Alvefur <zash@zash.se>
parents: 7979
diff changeset
   127
			return true;
ec7cab8e744d util.array: Add method for filtering out duplicate values
Kim Alvefur <zash@zash.se>
parents: 7979
diff changeset
   128
		end
ec7cab8e744d util.array: Add method for filtering out duplicate values
Kim Alvefur <zash@zash.se>
parents: 7979
diff changeset
   129
	end);
ec7cab8e744d util.array: Add method for filtering out duplicate values
Kim Alvefur <zash@zash.se>
parents: 7979
diff changeset
   130
end
ec7cab8e744d util.array: Add method for filtering out duplicate values
Kim Alvefur <zash@zash.se>
parents: 7979
diff changeset
   131
4439
1c8d2c0d02db util.array: Add pluck() method to pick a given property from each item
Matthew Wild <mwild1@gmail.com>
parents: 4387
diff changeset
   132
function array_base.pluck(outa, ina, key)
7022
abcd5ec3ee41 util.array: Fix minory style issues
Kim Alvefur <zash@zash.se>
parents: 6780
diff changeset
   133
	for i = 1, #ina do
4439
1c8d2c0d02db util.array: Add pluck() method to pick a given property from each item
Matthew Wild <mwild1@gmail.com>
parents: 4387
diff changeset
   134
		outa[i] = ina[i][key];
1c8d2c0d02db util.array: Add pluck() method to pick a given property from each item
Matthew Wild <mwild1@gmail.com>
parents: 4387
diff changeset
   135
	end
1c8d2c0d02db util.array: Add pluck() method to pick a given property from each item
Matthew Wild <mwild1@gmail.com>
parents: 4387
diff changeset
   136
	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
   137
end
1c8d2c0d02db util.array: Add pluck() method to pick a given property from each item
Matthew Wild <mwild1@gmail.com>
parents: 4387
diff changeset
   138
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
   139
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
   140
	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
   141
	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
   142
		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
   143
		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
   144
		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
   145
		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
   146
			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
   147
			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
   148
		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
   149
	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
   150
		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
   151
		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
   152
			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
   153
		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
   154
	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
   155
	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
   156
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
   157
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
   158
--- These methods only mutate the array
7703
0d70410efdcf util.array: Remove unused arguments [luacheck]
Kim Alvefur <zash@zash.se>
parents: 7702
diff changeset
   159
function array_methods:shuffle()
918
967edf874df7 util.array: New array library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   160
	local len = #self;
7022
abcd5ec3ee41 util.array: Fix minory style issues
Kim Alvefur <zash@zash.se>
parents: 6780
diff changeset
   161
	for i = 1, #self do
abcd5ec3ee41 util.array: Fix minory style issues
Kim Alvefur <zash@zash.se>
parents: 6780
diff changeset
   162
		local r = math_random(i, len);
918
967edf874df7 util.array: New array library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   163
		self[i], self[r] = self[r], self[i];
967edf874df7 util.array: New array library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   164
	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
   165
	return self;
918
967edf874df7 util.array: New array library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   166
end
967edf874df7 util.array: New array library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   167
7702
9c40d0be2295 util.array: Rename arguments to avoid name clash [luacheck]
Kim Alvefur <zash@zash.se>
parents: 7023
diff changeset
   168
function array_methods:append(ina)
9c40d0be2295 util.array: Rename arguments to avoid name clash [luacheck]
Kim Alvefur <zash@zash.se>
parents: 7023
diff changeset
   169
	local len, len2 = #self, #ina;
7022
abcd5ec3ee41 util.array: Fix minory style issues
Kim Alvefur <zash@zash.se>
parents: 6780
diff changeset
   170
	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
   171
		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
   172
	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
   173
	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
   174
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
   175
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
   176
function array_methods:push(x)
4449
ca74d8ed1a15 util.array: Avoid globals.
Waqas Hussain <waqas20@gmail.com>
parents: 4448
diff changeset
   177
	t_insert(self, x);
4448
d745f4c28294 util.array: Make array:push() chainable.
Waqas Hussain <waqas20@gmail.com>
parents: 4440
diff changeset
   178
	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
   179
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
   180
7023
6ab9c691c4c6 util.array: Just use table.remove as array:pop()
Kim Alvefur <zash@zash.se>
parents: 7022
diff changeset
   181
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
   182
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
   183
function array_methods:concat(sep)
4449
ca74d8ed1a15 util.array: Avoid globals.
Waqas Hussain <waqas20@gmail.com>
parents: 4448
diff changeset
   184
	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
   185
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
   186
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
   187
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
   188
	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
   189
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
   190
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
   191
--- 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
   192
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
   193
	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
   194
	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
   195
		var = f(s, var);
7022
abcd5ec3ee41 util.array: Fix minory style issues
Kim Alvefur <zash@zash.se>
parents: 6780
diff changeset
   196
		if var == nil then break; end
4449
ca74d8ed1a15 util.array: Avoid globals.
Waqas Hussain <waqas20@gmail.com>
parents: 4448
diff changeset
   197
		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
   198
	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
   199
	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
   200
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
   201
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
   202
---
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
   203
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
   204
-- 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
   205
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
   206
	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
   207
	-- 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
   208
	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
   209
		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
   210
		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
   211
	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
   212
	-- 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
   213
	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
   214
		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
   215
	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
   216
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
   217
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
   218
return array;