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;