diff --git a/src/Illuminate/Support/Arr.php b/src/Illuminate/Support/Arr.php index e7f0ad091bdd..78f8acc6db6d 100755 --- a/src/Illuminate/Support/Arr.php +++ b/src/Illuminate/Support/Arr.php @@ -69,13 +69,23 @@ public static function collapse($array) */ public static function crossJoin(...$arrays) { - return array_reduce($arrays, function ($results, $array) { - return static::collapse(array_map(function ($parent) use ($array) { - return array_map(function ($item) use ($parent) { - return array_merge($parent, [$item]); - }, $array); - }, $results)); - }, [[]]); + $results = [[]]; + + foreach ($arrays as $index => $array) { + $append = []; + + foreach ($results as $product) { + foreach ($array as $item) { + $product[$index] = $item; + + $append[] = $product; + } + } + + $results = $append; + } + + return $results; } /** diff --git a/tests/Support/SupportArrTest.php b/tests/Support/SupportArrTest.php index eca6f0ba2b1b..cc7e841a2693 100644 --- a/tests/Support/SupportArrTest.php +++ b/tests/Support/SupportArrTest.php @@ -38,25 +38,25 @@ public function testCollapse() public function testCrossJoin() { // Single dimension - $this->assertEquals( + $this->assertSame( [[1, 'a'], [1, 'b'], [1, 'c']], Arr::crossJoin([1], ['a', 'b', 'c']) ); // Square matrix - $this->assertEquals( + $this->assertSame( [[1, 'a'], [1, 'b'], [2, 'a'], [2, 'b']], Arr::crossJoin([1, 2], ['a', 'b']) ); // Rectangular matrix - $this->assertEquals( + $this->assertSame( [[1, 'a'], [1, 'b'], [1, 'c'], [2, 'a'], [2, 'b'], [2, 'c']], Arr::crossJoin([1, 2], ['a', 'b', 'c']) ); // 3D matrix - $this->assertEquals( + $this->assertSame( [ [1, 'a', 'I'], [1, 'a', 'II'], [1, 'a', 'III'], [1, 'b', 'I'], [1, 'b', 'II'], [1, 'b', 'III'], @@ -67,7 +67,17 @@ public function testCrossJoin() ); // With 1 empty dimension - $this->assertEquals([], Arr::crossJoin([1, 2], [], ['I', 'II', 'III'])); + $this->assertSame([], Arr::crossJoin([], ['a', 'b'], ['I', 'II', 'III'])); + $this->assertSame([], Arr::crossJoin([1, 2], [], ['I', 'II', 'III'])); + $this->assertSame([], Arr::crossJoin([1, 2], ['a', 'b'], [])); + + // With empty arrays + $this->assertSame([], Arr::crossJoin([], [], [])); + $this->assertSame([], Arr::crossJoin([], [])); + $this->assertSame([], Arr::crossJoin([])); + + // Not really a proper usage, still, test for preserving BC + $this->assertSame([[]], Arr::crossJoin()); } public function testDivide()