Software /
code /
prosody
Comparison
util/array.lua @ 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
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Mon, 05 Oct 2009 14:38:04 +0100 |
parent | 1522:569d58d21612 |
child | 1915:e9d5406caf8c |
comparison
equal
deleted
inserted
replaced
1904:0aa55a5dafde | 1905:e3e0a17e0b33 |
---|---|
4 -- | 4 -- |
5 -- This project is MIT/X11 licensed. Please see the | 5 -- This project is MIT/X11 licensed. Please see the |
6 -- COPYING file in the source package for more information. | 6 -- COPYING file in the source package for more information. |
7 -- | 7 -- |
8 | 8 |
9 local t_insert, t_sort, t_remove, t_concat | |
10 = table.insert, table.sort, table.remove, table.concat; | |
11 | |
9 local array = {}; | 12 local array = {}; |
13 local array_base = {}; | |
14 local array_methods = {}; | |
15 local array_mt = { __index = array_methods, __tostring = function (array) return array:concat(", "); end }; | |
10 | 16 |
11 local array_mt = { __index = array, __tostring = function (array) return array:concat(", "); end }; | |
12 local function new_array(_, t) | 17 local function new_array(_, t) |
13 return setmetatable(t or {}, array_mt); | 18 return setmetatable(t or {}, array_mt); |
14 end | 19 end |
15 | 20 |
16 function array_mt.__add(a1, a2) | 21 function array_mt.__add(a1, a2) |
18 return res:append(a1):append(a2); | 23 return res:append(a1):append(a2); |
19 end | 24 end |
20 | 25 |
21 setmetatable(array, { __call = new_array }); | 26 setmetatable(array, { __call = new_array }); |
22 | 27 |
23 function array:map(func, t2) | 28 function array_base.map(outa, ina, func) |
24 local t2 = t2 or array{}; | 29 for k,v in ipairs(ina) do |
25 for k,v in ipairs(self) do | 30 outa[k] = func(v); |
26 t2[k] = func(v); | |
27 end | 31 end |
28 return t2; | 32 return outa; |
29 end | 33 end |
30 | 34 |
31 function array:filter(func, t2) | 35 function array_base.filter(outa, ina, func) |
32 local t2 = t2 or array{}; | 36 for k,v in ipairs(ina) do |
33 for k,v in ipairs(self) do | |
34 if func(v) then | 37 if func(v) then |
35 t2:push(v); | 38 outa:push(v); |
36 end | 39 end |
37 end | 40 end |
38 return t2; | 41 return outa; |
39 end | 42 end |
40 | 43 |
44 function array_base.sort(outa, ina, ...) | |
45 if ina ~= outa then | |
46 outa:append(ina); | |
47 end | |
48 t_sort(outa, ...); | |
49 return outa; | |
50 end | |
41 | 51 |
42 array.push = table.insert; | 52 --- These methods only mutate |
43 array.pop = table.remove; | 53 function array_methods:random() |
44 array.sort = table.sort; | |
45 array.concat = table.concat; | |
46 array.length = function (t) return #t; end | |
47 | |
48 function array:random() | |
49 return self[math.random(1,#self)]; | 54 return self[math.random(1,#self)]; |
50 end | 55 end |
51 | 56 |
52 function array:shuffle() | 57 function array_methods:shuffle(outa, ina) |
53 local len = #self; | 58 local len = #self; |
54 for i=1,#self do | 59 for i=1,#self do |
55 local r = math.random(i,len); | 60 local r = math.random(i,len); |
56 self[i], self[r] = self[r], self[i]; | 61 self[i], self[r] = self[r], self[i]; |
57 end | 62 end |
58 return self; | 63 return self; |
59 end | 64 end |
60 | 65 |
61 function array:reverse() | 66 function array_methods:reverse() |
62 local len = #self-1; | 67 local len = #self-1; |
63 for i=len,1,-1 do | 68 for i=len,1,-1 do |
64 self:push(self[i]); | 69 self:push(self[i]); |
65 self:pop(i); | 70 self:pop(i); |
66 end | 71 end |
67 return self; | 72 return self; |
68 end | 73 end |
69 | 74 |
70 function array:append(array) | 75 function array_methods:append(array) |
71 local len,len2 = #self, #array; | 76 local len,len2 = #self, #array; |
72 for i=1,len2 do | 77 for i=1,len2 do |
73 self[len+i] = array[i]; | 78 self[len+i] = array[i]; |
74 end | 79 end |
75 return self; | 80 return self; |
76 end | 81 end |
77 | 82 |
83 array_methods.push = table.insert; | |
84 array_methods.pop = table.remove; | |
85 array_methods.concat = table.concat; | |
86 array_methods.length = function (t) return #t; end | |
87 | |
88 --- These methods always create a new array | |
78 function array.collect(f, s, var) | 89 function array.collect(f, s, var) |
79 local t, var = {}; | 90 local t, var = {}; |
80 while true do | 91 while true do |
81 var = f(s, var); | 92 var = f(s, var); |
82 if var == nil then break; end | 93 if var == nil then break; end |
83 table.insert(t, var); | 94 table.insert(t, var); |
84 end | 95 end |
85 return setmetatable(t, array_mt); | 96 return setmetatable(t, array_mt); |
86 end | 97 end |
87 | 98 |
99 --- | |
100 | |
101 -- Setup methods from array_base | |
102 for method, f in pairs(array_base) do | |
103 local method = method; -- Yes, this is necessary :) | |
104 local base_method = f; | |
105 -- Setup global array method which makes new array | |
106 array[method] = function (old_a, ...) | |
107 local a = new_array(); | |
108 return base_method(a, old_a, ...); | |
109 end | |
110 -- Setup per-array (mutating) method | |
111 array_methods[method] = function (self, ...) | |
112 return base_method(self, self, ...); | |
113 end | |
114 end | |
115 | |
88 _G.array = array; | 116 _G.array = array; |
89 module("array"); | 117 module("array"); |
90 | 118 |
91 return array; | 119 return array; |