X-Git-Url: https://git.enpas.org/?a=blobdiff_plain;f=util%2Farray.lua;h=d4ab1771111cb543db105942892005177dbbd612;hb=28c63835bdf4bfc9a8d79abba45f726caf320bb5;hp=6c1f04606642bc5cdb700f36e289a0aa655d319e;hpb=c72eea870ae98d356e03636a40f6cff16c2f6da1;p=prosody.git diff --git a/util/array.lua b/util/array.lua index 6c1f0460..d4ab1771 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. -- @@ -9,12 +9,22 @@ local t_insert, t_sort, t_remove, t_concat = table.insert, table.sort, table.remove, table.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 (array) return "{"..array:concat(", ").."}"; end }; -local function new_array(_, t) +local function new_array(self, t, _s, _var) + if type(t) == "function" then -- Assume iterator + t = self.collect(t, _s, _var); + end return setmetatable(t or {}, array_mt); end @@ -25,6 +35,15 @@ end setmetatable(array, { __call = new_array }); +-- Read-only methods +function array_methods:random() + return self[math_random(1,#self)]; +end + +-- These methods can be called two ways: +-- array.method(existing_array, [params [, ...]]) -- Create new array for result +-- existing_array:method([params, ...]) -- Transform existing array into result +-- function array_base.map(outa, ina, func) for k,v in ipairs(ina) do outa[k] = func(v); @@ -42,13 +61,13 @@ function array_base.filter(outa, ina, func) write = write + 1; end end - + if inplace and write <= start_length then for i=write,start_length do outa[i] = nil; end end - + return outa; end @@ -60,29 +79,42 @@ function array_base.sort(outa, ina, ...) return outa; end ---- These methods only mutate -function array_methods:random() - return self[math.random(1,#self)]; +function array_base.pluck(outa, ina, key) + for i=1,#ina do + outa[i] = ina[i][key]; + end + return outa; end +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 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); + local r = math_random(i,len); self[i], self[r] = self[r], self[i]; end return self; end -function array_methods:reverse() - local len = #self-1; - for i=len,1,-1 do - self:push(self[i]); - self:pop(i); - end - return self; -end - function array_methods:append(array) local len,len2 = #self, #array; for i=1,len2 do @@ -91,18 +123,32 @@ function array_methods:append(array) return self; end -array_methods.push = table.insert; -array_methods.pop = table.remove; -array_methods.concat = table.concat; -array_methods.length = function (t) return #t; end +function array_methods:push(x) + t_insert(self, x); + return self; +end + +function array_methods:pop(x) + local v = self[x]; + t_remove(self, x); + return v; +end + +function array_methods:concat(sep) + return t_concat(array.map(self, tostring), sep); +end + +function array_methods:length() + return #self; +end --- These methods always create a new array function array.collect(f, s, var) - local t, var = {}; + local t = {}; while true do var = f(s, var); if var == nil then break; end - table.insert(t, var); + t_insert(t, var); end return setmetatable(t, array_mt); end @@ -123,7 +169,4 @@ for method, f in pairs(array_base) do end end -_G.array = array; -module("array"); - return array;