Software /
code /
prosody
Annotate
util/array.lua @ 1921:5ac99cd46545
util.array: Fix for array:filter() (in-place filtering)
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Mon, 05 Oct 2009 17:56:31 +0100 |
parent | 1918:dd35d07d673f |
child | 1922:d5fe0f9b377a |
rev | line source |
---|---|
1522
569d58d21612
Add copyright header to those files missing one
Matthew Wild <mwild1@gmail.com>
parents:
1373
diff
changeset
|
1 -- Prosody IM |
569d58d21612
Add copyright header to those files missing one
Matthew Wild <mwild1@gmail.com>
parents:
1373
diff
changeset
|
2 -- Copyright (C) 2008-2009 Matthew Wild |
569d58d21612
Add copyright header to those files missing one
Matthew Wild <mwild1@gmail.com>
parents:
1373
diff
changeset
|
3 -- Copyright (C) 2008-2009 Waqas Hussain |
569d58d21612
Add copyright header to those files missing one
Matthew Wild <mwild1@gmail.com>
parents:
1373
diff
changeset
|
4 -- |
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 |
1918
dd35d07d673f
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
|
9 local t_insert, t_sort, t_remove, t_concat |
dd35d07d673f
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
|
10 = table.insert, table.sort, table.remove, table.concat; |
918 | 11 |
1918
dd35d07d673f
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
|
12 local array = {}; |
dd35d07d673f
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
|
13 local array_base = {}; |
dd35d07d673f
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
|
14 local array_methods = {}; |
dd35d07d673f
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
|
15 local array_mt = { __index = array_methods, __tostring = function (array) return array:concat(", "); end }; |
dd35d07d673f
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
|
16 |
920
e302cbc9d036
util.array: Expose array.* functions, to be used for unwrapped arrays
Matthew Wild <mwild1@gmail.com>
parents:
918
diff
changeset
|
17 local function new_array(_, t) |
918 | 18 return setmetatable(t or {}, array_mt); |
19 end | |
20 | |
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
|
21 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
|
22 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
|
23 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
|
24 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
|
25 |
920
e302cbc9d036
util.array: Expose array.* functions, to be used for unwrapped arrays
Matthew Wild <mwild1@gmail.com>
parents:
918
diff
changeset
|
26 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
|
27 |
1918
dd35d07d673f
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 function array_base.map(outa, ina, func) |
dd35d07d673f
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
|
29 for k,v in ipairs(ina) do |
dd35d07d673f
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
|
30 outa[k] = func(v); |
918 | 31 end |
1918
dd35d07d673f
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
|
32 return outa; |
918 | 33 end |
34 | |
1918
dd35d07d673f
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
|
35 function array_base.filter(outa, ina, func) |
1921
5ac99cd46545
util.array: Fix for array:filter() (in-place filtering)
Matthew Wild <mwild1@gmail.com>
parents:
1918
diff
changeset
|
36 local inplace, start_length = ina == outa, #ina; |
5ac99cd46545
util.array: Fix for array:filter() (in-place filtering)
Matthew Wild <mwild1@gmail.com>
parents:
1918
diff
changeset
|
37 local write = 1; |
5ac99cd46545
util.array: Fix for array:filter() (in-place filtering)
Matthew Wild <mwild1@gmail.com>
parents:
1918
diff
changeset
|
38 for read=1,start_length do |
5ac99cd46545
util.array: Fix for array:filter() (in-place filtering)
Matthew Wild <mwild1@gmail.com>
parents:
1918
diff
changeset
|
39 local v = ina[read]; |
918 | 40 if func(v) then |
1921
5ac99cd46545
util.array: Fix for array:filter() (in-place filtering)
Matthew Wild <mwild1@gmail.com>
parents:
1918
diff
changeset
|
41 outa[write] = v; |
5ac99cd46545
util.array: Fix for array:filter() (in-place filtering)
Matthew Wild <mwild1@gmail.com>
parents:
1918
diff
changeset
|
42 write = write + 1; |
918 | 43 end |
44 end | |
1921
5ac99cd46545
util.array: Fix for array:filter() (in-place filtering)
Matthew Wild <mwild1@gmail.com>
parents:
1918
diff
changeset
|
45 |
5ac99cd46545
util.array: Fix for array:filter() (in-place filtering)
Matthew Wild <mwild1@gmail.com>
parents:
1918
diff
changeset
|
46 if inplace and write < start_length then |
5ac99cd46545
util.array: Fix for array:filter() (in-place filtering)
Matthew Wild <mwild1@gmail.com>
parents:
1918
diff
changeset
|
47 for i=write,start_length do |
5ac99cd46545
util.array: Fix for array:filter() (in-place filtering)
Matthew Wild <mwild1@gmail.com>
parents:
1918
diff
changeset
|
48 outa[i] = nil; |
5ac99cd46545
util.array: Fix for array:filter() (in-place filtering)
Matthew Wild <mwild1@gmail.com>
parents:
1918
diff
changeset
|
49 end |
5ac99cd46545
util.array: Fix for array:filter() (in-place filtering)
Matthew Wild <mwild1@gmail.com>
parents:
1918
diff
changeset
|
50 end |
5ac99cd46545
util.array: Fix for array:filter() (in-place filtering)
Matthew Wild <mwild1@gmail.com>
parents:
1918
diff
changeset
|
51 |
1918
dd35d07d673f
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
|
52 return outa; |
918 | 53 end |
54 | |
1918
dd35d07d673f
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
|
55 function array_base.sort(outa, ina, ...) |
dd35d07d673f
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
|
56 if ina ~= outa then |
dd35d07d673f
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
|
57 outa:append(ina); |
dd35d07d673f
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
|
58 end |
dd35d07d673f
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
|
59 t_sort(outa, ...); |
dd35d07d673f
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
|
60 return outa; |
dd35d07d673f
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
|
61 end |
918 | 62 |
1918
dd35d07d673f
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
|
63 --- These methods only mutate |
dd35d07d673f
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
|
64 function array_methods:random() |
918 | 65 return self[math.random(1,#self)]; |
66 end | |
67 | |
1918
dd35d07d673f
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
|
68 function array_methods:shuffle(outa, ina) |
918 | 69 local len = #self; |
70 for i=1,#self do | |
71 local r = math.random(i,len); | |
72 self[i], self[r] = self[r], self[i]; | |
73 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
|
74 return self; |
918 | 75 end |
76 | |
1918
dd35d07d673f
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
|
77 function array_methods:reverse() |
922
0e45234360cd
util.array: Add :reverse() method
Matthew Wild <mwild1@gmail.com>
parents:
920
diff
changeset
|
78 local len = #self-1; |
0e45234360cd
util.array: Add :reverse() method
Matthew Wild <mwild1@gmail.com>
parents:
920
diff
changeset
|
79 for i=len,1,-1 do |
0e45234360cd
util.array: Add :reverse() method
Matthew Wild <mwild1@gmail.com>
parents:
920
diff
changeset
|
80 self:push(self[i]); |
0e45234360cd
util.array: Add :reverse() method
Matthew Wild <mwild1@gmail.com>
parents:
920
diff
changeset
|
81 self:pop(i); |
0e45234360cd
util.array: Add :reverse() method
Matthew Wild <mwild1@gmail.com>
parents:
920
diff
changeset
|
82 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
|
83 return self; |
922
0e45234360cd
util.array: Add :reverse() method
Matthew Wild <mwild1@gmail.com>
parents:
920
diff
changeset
|
84 end |
0e45234360cd
util.array: Add :reverse() method
Matthew Wild <mwild1@gmail.com>
parents:
920
diff
changeset
|
85 |
1918
dd35d07d673f
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
|
86 function array_methods:append(array) |
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
|
87 local len,len2 = #self, #array; |
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
|
88 for i=1,len2 do |
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
|
89 self[len+i] = array[i]; |
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
|
90 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
|
91 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
|
92 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
|
93 |
1918
dd35d07d673f
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 array_methods.push = table.insert; |
dd35d07d673f
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
|
95 array_methods.pop = table.remove; |
dd35d07d673f
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 array_methods.concat = table.concat; |
dd35d07d673f
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
|
97 array_methods.length = function (t) return #t; end |
dd35d07d673f
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 |
dd35d07d673f
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
|
99 --- 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
|
100 function array.collect(f, s, var) |
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
|
101 local t, var = {}; |
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
|
102 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
|
103 var = f(s, var); |
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
|
104 if var == nil then break; 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
|
105 table.insert(t, var); |
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
|
106 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
|
107 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
|
108 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
|
109 |
1918
dd35d07d673f
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
|
110 --- |
dd35d07d673f
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
|
111 |
dd35d07d673f
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 -- Setup methods from array_base |
dd35d07d673f
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 for method, f in pairs(array_base) do |
dd35d07d673f
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 local method = method; -- Yes, this is necessary :) |
dd35d07d673f
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 local base_method = f; |
dd35d07d673f
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 -- Setup global array method which makes new array |
dd35d07d673f
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 array[method] = function (old_a, ...) |
dd35d07d673f
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 local a = new_array(); |
dd35d07d673f
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
|
119 return base_method(a, old_a, ...); |
dd35d07d673f
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
|
120 end |
dd35d07d673f
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
|
121 -- Setup per-array (mutating) method |
dd35d07d673f
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
|
122 array_methods[method] = function (self, ...) |
dd35d07d673f
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
|
123 return base_method(self, self, ...); |
dd35d07d673f
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
|
124 end |
dd35d07d673f
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
|
125 end |
dd35d07d673f
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
|
126 |
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
|
127 _G.array = array; |
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
|
128 module("array"); |
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
|
129 |
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
|
130 return array; |