util.array: Add :slice() method + tests
Behaviour follows the same logic as string.sub (so yes, 1-indexed).
--- a/spec/util_array_spec.lua Sun Sep 12 10:31:02 2021 +0100
+++ b/spec/util_array_spec.lua Sun Sep 12 10:50:20 2021 +0100
@@ -148,6 +148,25 @@
end);
end);
+ describe("slice", function ()
+ it("works", function ()
+ local a = array({ "a", "b", "c" });
+ assert.equal(array.slice(a, 1, 2), array{ "a", "b" });
+ assert.equal(array.slice(a, 1, 3), array{ "a", "b", "c" });
+ assert.equal(array.slice(a, 2, 3), array{ "b", "c" });
+ assert.equal(array.slice(a, 2), array{ "b", "c" });
+ assert.equal(array.slice(a, -4), array{ "a", "b", "c" });
+ assert.equal(array.slice(a, -3), array{ "a", "b", "c" });
+ assert.equal(array.slice(a, -2), array{ "b", "c" });
+ assert.equal(array.slice(a, -1), array{ "c" });
+ end);
+
+ it("can mutate", function ()
+ local a = array({ "a", "b", "c" });
+ assert.equal(a:slice(-1), array{"c"});
+ assert.equal(a, array{"c"});
+ end);
+ end);
end);
-- TODO The various array.foo(array ina, array outa) functions
--- a/util/array.lua Sun Sep 12 10:31:02 2021 +0100
+++ b/util/array.lua Sun Sep 12 10:50:20 2021 +0100
@@ -114,6 +114,40 @@
return outa;
end
+function array_base.slice(outa, ina, i, j)
+ if j == nil then
+ j = -1;
+ end
+ if j < 0 then
+ j = #ina + (j+1);
+ end
+ if i < 0 then
+ i = #ina + (i+1);
+ end
+ if i < 1 then
+ i = 1;
+ end
+ if j > #ina then
+ j = #ina;
+ end
+ if i > j then
+ for idx = 1, #outa do
+ outa[idx] = nil;
+ end
+ return outa;
+ end
+
+ for idx = 1, 1+j-i do
+ outa[idx] = ina[i+(idx-1)];
+ end
+ if ina == outa then
+ for idx = 2+j-i, #outa do
+ outa[idx] = nil;
+ end
+ end
+ return outa;
+end
+
function array_base.sort(outa, ina, ...)
if ina ~= outa then
outa:append(ina);