diff options
Diffstat (limited to 'util/array.lua')
-rw-r--r-- | util/array.lua | 98 |
1 files changed, 64 insertions, 34 deletions
diff --git a/util/array.lua b/util/array.lua index 2d58e7fb..150b4355 100644 --- a/util/array.lua +++ b/util/array.lua @@ -1,7 +1,7 @@ -- Prosody IM -- Copyright (C) 2008-2010 Matthew Wild -- Copyright (C) 2008-2010 Waqas Hussain --- +-- -- This project is MIT/X11 licensed. Please see the -- COPYING file in the source package for more information. -- @@ -11,13 +11,15 @@ local t_insert, t_sort, t_remove, t_concat local setmetatable = setmetatable; local math_random = math.random; +local math_floor = math.floor; local pairs, ipairs = pairs, ipairs; local tostring = tostring; +local type = type; local array = {}; local array_base = {}; local array_methods = {}; -local array_mt = { __index = array_methods, __tostring = function (array) return "{"..array:concat(", ").."}"; end }; +local array_mt = { __index = array_methods, __tostring = function (self) return "{"..self:concat(", ").."}"; end }; local function new_array(self, t, _s, _var) if type(t) == "function" then -- Assume iterator @@ -31,11 +33,24 @@ function array_mt.__add(a1, a2) return res:append(a1):append(a2); end +function array_mt.__eq(a, b) + if #a == #b then + for i = 1, #a do + if a[i] ~= b[i] then + return false; + end + end + else + return false; + end + return true; +end + setmetatable(array, { __call = new_array }); -- Read-only methods function array_methods:random() - return self[math_random(1,#self)]; + return self[math_random(1, #self)]; end -- These methods can be called two ways: @@ -43,7 +58,7 @@ end -- existing_array:method([params, ...]) -- Transform existing array into result -- function array_base.map(outa, ina, func) - for k,v in ipairs(ina) do + for k, v in ipairs(ina) do outa[k] = func(v); end return outa; @@ -52,20 +67,20 @@ end function array_base.filter(outa, ina, func) local inplace, start_length = ina == outa, #ina; local write = 1; - for read=1,start_length do + for read = 1, start_length do local v = ina[read]; if func(v) then outa[write] = v; write = write + 1; end end - + if inplace and write <= start_length then - for i=write,start_length do + for i = write, start_length do outa[i] = nil; end end - + return outa; end @@ -77,36 +92,58 @@ function array_base.sort(outa, ina, ...) return outa; end +function array_base.unique(outa, ina) + local seen = {}; + return array_base.filter(outa, ina, function (item) + if seen[item] then + return false; + else + seen[item] = true; + return true; + end + end); +end + function array_base.pluck(outa, ina, key) - for i=1,#ina do + for i = 1, #ina do outa[i] = ina[i][key]; end return outa; end ---- These methods only mutate the array -function array_methods:shuffle(outa, ina) - local len = #self; - for i=1,#self do - local r = math_random(i,len); - self[i], self[r] = self[r], self[i]; +function array_base.reverse(outa, ina) + local len = #ina; + if ina == outa then + local middle = math_floor(len/2); + len = len + 1; + local o; -- opposite + for i = 1, middle do + o = len - i; + outa[i], outa[o] = outa[o], outa[i]; + end + else + local off = len + 1; + for i = 1, len do + outa[i] = ina[off - i]; + end end - return self; + return outa; end -function array_methods:reverse() - local len = #self-1; - for i=len,1,-1 do - self:push(self[i]); - self:pop(i); +--- These methods only mutate the array +function array_methods:shuffle() + local len = #self; + for i = 1, #self do + local r = math_random(i, len); + self[i], self[r] = self[r], self[i]; end return self; end -function array_methods:append(array) - local len,len2 = #self, #array; - for i=1,len2 do - self[len+i] = array[i]; +function array_methods:append(ina) + local len, len2 = #self, #ina; + for i = 1, len2 do + self[len+i] = ina[i]; end return self; end @@ -116,11 +153,7 @@ function array_methods:push(x) return self; end -function array_methods:pop(x) - local v = self[x]; - t_remove(self, x); - return v; -end +array_methods.pop = t_remove; function array_methods:concat(sep) return t_concat(array.map(self, tostring), sep); @@ -135,7 +168,7 @@ function array.collect(f, s, var) local t = {}; while true do var = f(s, var); - if var == nil then break; end + if var == nil then break; end t_insert(t, var); end return setmetatable(t, array_mt); @@ -157,7 +190,4 @@ for method, f in pairs(array_base) do end end -_G.array = array; -module("array"); - return array; |