util.array: Add :slice() method + tests
authorMatthew Wild <mwild1@gmail.com>
Sun, 12 Sep 2021 10:50:20 +0100
changeset 11791 3ae6fa901a8b
parent 11790 39164ea2ab9e
child 11792 1ceee8becb1a
util.array: Add :slice() method + tests Behaviour follows the same logic as string.sub (so yes, 1-indexed).
spec/util_array_spec.lua
util/array.lua
--- 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);