2 -- Copyright (C) 2008-2010 Matthew Wild
3 -- Copyright (C) 2008-2010 Waqas Hussain
5 -- This project is MIT/X11 licensed. Please see the
6 -- COPYING file in the source package for more information.
9 local t_insert, t_sort, t_remove, t_concat
10 = table.insert, table.sort, table.remove, table.concat;
12 local setmetatable = setmetatable;
13 local math_random = math.random;
14 local math_floor = math.floor;
15 local pairs, ipairs = pairs, ipairs;
16 local tostring = tostring;
20 local array_base = {};
21 local array_methods = {};
22 local array_mt = { __index = array_methods, __tostring = function (array) return "{"..array:concat(", ").."}"; end };
24 local function new_array(self, t, _s, _var)
25 if type(t) == "function" then -- Assume iterator
26 t = self.collect(t, _s, _var);
28 return setmetatable(t or {}, array_mt);
31 function array_mt.__add(a1, a2)
32 local res = new_array();
33 return res:append(a1):append(a2);
36 setmetatable(array, { __call = new_array });
39 function array_methods:random()
40 return self[math_random(1, #self)];
43 -- These methods can be called two ways:
44 -- array.method(existing_array, [params [, ...]]) -- Create new array for result
45 -- existing_array:method([params, ...]) -- Transform existing array into result
47 function array_base.map(outa, ina, func)
48 for k, v in ipairs(ina) do
54 function array_base.filter(outa, ina, func)
55 local inplace, start_length = ina == outa, #ina;
57 for read = 1, start_length do
65 if inplace and write <= start_length then
66 for i = write, start_length do
74 function array_base.sort(outa, ina, ...)
82 function array_base.pluck(outa, ina, key)
84 outa[i] = ina[i][key];
89 function array_base.reverse(outa, ina)
92 local middle = math_floor(len/2);
97 outa[i], outa[o] = outa[o], outa[i];
102 outa[i] = ina[off - i];
108 --- These methods only mutate the array
109 function array_methods:shuffle(outa, ina)
112 local r = math_random(i, len);
113 self[i], self[r] = self[r], self[i];
118 function array_methods:append(array)
119 local len, len2 = #self, #array;
121 self[len+i] = array[i];
126 function array_methods:push(x)
131 array_methods.pop = t_remove;
133 function array_methods:concat(sep)
134 return t_concat(array.map(self, tostring), sep);
137 function array_methods:length()
141 --- These methods always create a new array
142 function array.collect(f, s, var)
146 if var == nil then break; end
149 return setmetatable(t, array_mt);
154 -- Setup methods from array_base
155 for method, f in pairs(array_base) do
156 local base_method = f;
157 -- Setup global array method which makes new array
158 array[method] = function (old_a, ...)
159 local a = new_array();
160 return base_method(a, old_a, ...);
162 -- Setup per-array (mutating) method
163 array_methods[method] = function (self, ...)
164 return base_method(self, self, ...);