From eb22dc73739badea0e81028863febb4a9b716f72 Mon Sep 17 00:00:00 2001 From: Benson Lee Date: Mon, 12 Jun 2017 16:02:20 -0700 Subject: [PATCH] Laravel 5.4.25 changes (#43) --- src/Illuminate/Support/Arr.php | 17 ++++ src/Illuminate/Support/Collection.php | 62 ++++++++++++- tests/Support/SupportCollectionTest.php | 113 ++++++++++++++++++++++++ 3 files changed, 191 insertions(+), 1 deletion(-) diff --git a/src/Illuminate/Support/Arr.php b/src/Illuminate/Support/Arr.php index 5f5302d..c6bf456 100644 --- a/src/Illuminate/Support/Arr.php +++ b/src/Illuminate/Support/Arr.php @@ -60,6 +60,23 @@ public static function collapse($array) return $results; } + /** + * Cross join the given arrays, returning all possible permutations. + * + * @param array ...$arrays + * @return 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)); + }, [[]]); + } + /** * Divide an array into two arrays. One with keys and the other with values. * diff --git a/src/Illuminate/Support/Collection.php b/src/Illuminate/Support/Collection.php index 4a879bd..cf190aa 100644 --- a/src/Illuminate/Support/Collection.php +++ b/src/Illuminate/Support/Collection.php @@ -65,12 +65,16 @@ public static function make($items = []) * @param callable $callback * @return static */ - public static function times($amount, callable $callback) + public static function times($amount, callable $callback = null) { if ($amount < 1) { return new static; } + if (is_null($callback)) { + return new static(range(1, $amount)); + } + return (new static(range(1, $amount)))->map($callback); } @@ -226,6 +230,19 @@ public function containsStrict($key, $value = null) return in_array($key, $this->items, true); } + /** + * Cross join with the given lists, returning all possible permutations. + * + * @param mixed ...$lists + * @return static + */ + public function crossJoin(...$lists) + { + return new static(Arr::crossJoin( + $this->items, ...array_map([$this, 'getArrayableItems'], $lists) + )); + } + /** * Get the items in the collection that are not present in the given items. * @@ -265,6 +282,19 @@ public function each(callable $callback) return $this; } + /** + * Execute a callback over each nested chunk of items. + * + * @param callable $callback + * @return static + */ + public function eachSpread(callable $callback) + { + return $this->each(function ($chunk) use ($callback) { + return $callback(...$chunk); + }); + } + /** * Determine if all items in the collection pass the given test. * @@ -704,6 +734,19 @@ public function map(callable $callback) return new static(array_combine($keys, $items)); } + /** + * Run a map over each nested chunk of items. + * + * @param callable $callback + * @return static + */ + public function mapSpread(callable $callback) + { + return $this->map(function ($chunk) use ($callback) { + return $callback(...$chunk); + }); + } + /** * Run a grouping map over the items. * @@ -948,6 +991,23 @@ public function push($value) return $this; } + /** + * Push all of the given items onto the collection. + * + * @param \Traversable $source + * @return self + */ + public function concat($source) + { + $result = new static($this); + + foreach ($source as $item) { + $result->push($item); + } + + return $result; + } + /** * Get and remove an item from the collection. * diff --git a/tests/Support/SupportCollectionTest.php b/tests/Support/SupportCollectionTest.php index a05adfa..ccc9e04 100644 --- a/tests/Support/SupportCollectionTest.php +++ b/tests/Support/SupportCollectionTest.php @@ -552,6 +552,25 @@ public function testEach() $this->assertEquals([1, 2, 'foo' => 'bar'], $result); } + public function testEachSpread() + { + $c = new Collection([[1, 'a'], [2, 'b']]); + + $result = []; + $c->eachSpread(function ($number, $character) use (&$result) { + $result[] = [$number, $character]; + }); + $this->assertEquals($c->all(), $result); + + $result = []; + $c->eachSpread(function ($number, $character) use (&$result) { + $result[] = [$number, $character]; + + return false; + }); + $this->assertEquals([[1, 'a']], $result); + } + public function testIntersectNull() { $c = new Collection(['id' => 1, 'first_word' => 'Hello']); @@ -646,6 +665,35 @@ public function testCollapseWithNestedCollactions() $this->assertEquals([1, 2, 3, 4, 5, 6], $data->collapse()->all()); } + public function testCrossJoin() + { + // Cross join with an array + $this->assertEquals( + [[1, 'a'], [1, 'b'], [2, 'a'], [2, 'b']], + (new Collection([1, 2]))->crossJoin(['a', 'b'])->all() + ); + + // Cross join with a collection + $this->assertEquals( + [[1, 'a'], [1, 'b'], [2, 'a'], [2, 'b']], + (new Collection([1, 2]))->crossJoin(new Collection(['a', 'b']))->all() + ); + + // Cross join with 2 collections + $this->assertEquals( + [ + [1, 'a', 'I'], [1, 'a', 'II'], + [1, 'b', 'I'], [1, 'b', 'II'], + [2, 'a', 'I'], [2, 'a', 'II'], + [2, 'b', 'I'], [2, 'b', 'II'], + ], + (new Collection([1, 2]))->crossJoin( + new Collection(['a', 'b']), + new Collection(['I', 'II']) + )->all() + ); + } + public function testSort() { $data = (new Collection([5, 3, 1, 2, 4]))->sort(); @@ -950,9 +998,12 @@ public function testTimesMethod() return 'slug-'.$number; }); + $range = Collection::times(5); + $this->assertEquals(['slug-1', 'slug-2'], $two->all()); $this->assertTrue($zero->isEmpty()); $this->assertTrue($negative->isEmpty()); + $this->assertEquals(range(1, 5), $range->all()); } public function testConstructMakeFromObject() @@ -1037,6 +1088,16 @@ public function testMap() $this->assertEquals(['first' => 'first-rolyat', 'last' => 'last-llewto'], $data->all()); } + public function testMapSpread() + { + $c = new Collection([[1, 'a'], [2, 'b']]); + + $result = $c->mapSpread(function ($number, $character) use (&$result) { + return "{$number}-{$character}"; + }); + $this->assertEquals(['1-a', '2-b'], $result->all()); + } + public function testFlatMap() { $data = new Collection([ @@ -1661,6 +1722,58 @@ public function testCombineWithCollection() $this->assertSame($expected, $actual); } + public function testConcatWithArray() + { + $expected = [ + 0 => 4, + 1 => 5, + 2 => 6, + 3 => 'a', + 4 => 'b', + 5 => 'c', + 6 => 'Jonny', + 7 => 'from', + 8 => 'Laroe', + 9 => 'Jonny', + 10 => 'from', + 11 => 'Laroe', + ]; + + $collection = new Collection([4, 5, 6]); + $collection = $collection->concat(['a', 'b', 'c']); + $collection = $collection->concat(['who' => 'Jonny', 'preposition' => 'from', 'where' => 'Laroe']); + $actual = $collection->concat(['who' => 'Jonny', 'preposition' => 'from', 'where' => 'Laroe'])->toArray(); + + $this->assertSame($expected, $actual); + } + + public function testConcatWithCollection() + { + $expected = [ + 0 => 4, + 1 => 5, + 2 => 6, + 3 => 'a', + 4 => 'b', + 5 => 'c', + 6 => 'Jonny', + 7 => 'from', + 8 => 'Laroe', + 9 => 'Jonny', + 10 => 'from', + 11 => 'Laroe', + ]; + + $firstCollection = new Collection([4, 5, 6]); + $secondCollection = new Collection(['a', 'b', 'c']); + $thirdCollection = new Collection(['who' => 'Jonny', 'preposition' => 'from', 'where' => 'Laroe']); + $firstCollection = $firstCollection->concat($secondCollection); + $firstCollection = $firstCollection->concat($thirdCollection); + $actual = $firstCollection->concat($thirdCollection)->toArray(); + + $this->assertSame($expected, $actual); + } + public function testReduce() { $data = new Collection([1, 2, 3]);