From 84da50b807f5cb181202bf0b157e5dcab8b8e9ed Mon Sep 17 00:00:00 2001 From: Nat Quayle Nelson Date: Thu, 10 Feb 2022 12:34:18 -0700 Subject: [PATCH] variadic intersect() function --- src/kiss/Kiss.hx | 1 + src/kiss/Prelude.hx | 16 ++++++++++++++++ src/test/cases/BasicTestCase.hx | 4 ++++ src/test/cases/BasicTestCase.kiss | 22 ++++++++++++++++++++++ 4 files changed, 43 insertions(+) diff --git a/src/kiss/Kiss.hx b/src/kiss/Kiss.hx index 078c374..7dcd7c7 100644 --- a/src/kiss/Kiss.hx +++ b/src/kiss/Kiss.hx @@ -116,6 +116,7 @@ class Kiss { "zipKeep" => Symbol("Prelude.zipKeep"), "zipDrop" => Symbol("Prelude.zipDrop"), "zipThrow" => Symbol("Prelude.zipThrow"), + "intersect" => Symbol("Prelude.intersect"), "joinPath" => Symbol("Prelude.joinPath"), "readDirectory" => Symbol("Prelude.readDirectory"), "substr" => Symbol("Prelude.substr"), diff --git a/src/kiss/Prelude.hx b/src/kiss/Prelude.hx index 587812e..b675467 100644 --- a/src/kiss/Prelude.hx +++ b/src/kiss/Prelude.hx @@ -246,6 +246,22 @@ class Prelude { public static var zipDrop:Function = Reflect.makeVarArgs(_zip.bind(_, Drop)); public static var zipThrow:Function = Reflect.makeVarArgs(_zip.bind(_, Throw)); + static function _intersect(iterables:Array):kiss.List> { + var iterators:Array> = [for (iterable in iterables) iterable.iterator()]; + + var intersections:Array> = [for (elem in iterators.shift()) [elem]]; + + for (iterator in iterators) { + intersections = cast _concat([for (elem in iterator) [for (intersection in intersections) intersection.concat([elem])]]); + } + + return intersections; + } + + // Return an array of every N-dimensional intersection of elements in N iterables. + // Callers should not rely on the order of the intersections + public static var intersect:Function = Reflect.makeVarArgs(_intersect); + public static function enumerate(l:kiss.List, startingIdx = 0):kiss.List> { return zipThrow(range(startingIdx, startingIdx + l.length, 1), l); } diff --git a/src/test/cases/BasicTestCase.hx b/src/test/cases/BasicTestCase.hx index bc58d56..499220f 100644 --- a/src/test/cases/BasicTestCase.hx +++ b/src/test/cases/BasicTestCase.hx @@ -335,6 +335,10 @@ class BasicTestCase extends Test { function testContains() { _testContains(); } + + function testIntersect() { + _testIntersect(); + } } class BasicObject { diff --git a/src/test/cases/BasicTestCase.kiss b/src/test/cases/BasicTestCase.kiss index ecb8ab6..e154f65 100644 --- a/src/test/cases/BasicTestCase.kiss +++ b/src/test/cases/BasicTestCase.kiss @@ -605,4 +605,26 @@ (assert !(contains "abc" "z")) (assert (contains [1 2 3] 1)) (assert !(contains [1 2 3] 5)) + (Assert.pass)) + +(function _testIntersect [] + (let [intersection2d + (for i (the Array> (intersect (.split "abc" "") (.split "xyz" ""))) (i.join "")) + intersection3d + (for i (the Array> (intersect (.split "abc" "") (.split "xyz" "") (.split "123" ""))) (i.join ""))] + (assert (contains intersection2d "ax")) + (assert (contains intersection2d "ay")) + (assert (contains intersection2d "az")) + (assert (contains intersection2d "bx")) + (assert (contains intersection2d "by")) + (assert (contains intersection2d "bz")) + (assert (contains intersection2d "cx")) + (assert (contains intersection2d "cy")) + (assert (contains intersection2d "cz")) + (assert (contains intersection3d "ax1")) + (assert (contains intersection3d "ax3")) + (assert (contains intersection3d "bx3")) + (assert (contains intersection3d "cy1")) + (assert (contains intersection3d "cy3")) + ) (Assert.pass)) \ No newline at end of file