aboutsummaryrefslogtreecommitdiffstats
path: root/util/array.lua
diff options
context:
space:
mode:
Diffstat (limited to 'util/array.lua')
-rw-r--r--util/array.lua98
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;