util.array: Add :slice() method + tests

Behaviour follows the same logic as string.sub (so yes, 1-indexed).
This commit is contained in:
Matthew Wild 2021-09-12 10:50:20 +01:00
parent eba0bacfda
commit edb6956ad5
2 changed files with 53 additions and 0 deletions

View file

@ -148,6 +148,25 @@ describe("util.array", function ()
end); end);
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); end);
-- TODO The various array.foo(array ina, array outa) functions -- TODO The various array.foo(array ina, array outa) functions

View file

@ -114,6 +114,40 @@ function array_base.filter(outa, ina, func)
return outa; return outa;
end 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, ...) function array_base.sort(outa, ina, ...)
if ina ~= outa then if ina ~= outa then
outa:append(ina); outa:append(ina);