From 4d4a76031a8a0f6e33439ffc4edbaadd67970ea6 Mon Sep 17 00:00:00 2001 From: Craig Morris Date: Thu, 1 Feb 2024 10:23:24 +1100 Subject: [PATCH] [10.x] Add Collection::select() method (#49845) * Add select method to Collection * style * Update Collection.php * Update LazyCollection.php --------- Co-authored-by: Craig Morris <> Co-authored-by: Taylor Otwell --- src/Illuminate/Collections/Arr.php | 14 +++++++ src/Illuminate/Collections/Collection.php | 21 ++++++++++ src/Illuminate/Collections/LazyCollection.php | 41 +++++++++++++++++++ tests/Support/SupportCollectionTest.php | 31 ++++++++++++++ 4 files changed, 107 insertions(+) diff --git a/src/Illuminate/Collections/Arr.php b/src/Illuminate/Collections/Arr.php index d1e4a40ae686..482bbadf0fb0 100644 --- a/src/Illuminate/Collections/Arr.php +++ b/src/Illuminate/Collections/Arr.php @@ -491,6 +491,20 @@ public static function only($array, $keys) return array_intersect_key($array, array_flip((array) $keys)); } + /** + * Select an array of values from an array. + * + * @param array $array + * @param array|string $keys + * @return array + */ + public static function select($array, $keys) + { + return static::map($array, function ($item) use ($keys) { + return array_intersect_key($item, array_flip((array) $keys)); + }); + } + /** * Pluck an array of values from an array. * diff --git a/src/Illuminate/Collections/Collection.php b/src/Illuminate/Collections/Collection.php index 7869e1ce65e0..6a2599946e7c 100644 --- a/src/Illuminate/Collections/Collection.php +++ b/src/Illuminate/Collections/Collection.php @@ -918,6 +918,27 @@ public function only($keys) return new static(Arr::only($this->items, $keys)); } + /** + * Select specific values from the items within the collection. + * + * @param \Illuminate\Support\Enumerable|array|string|null $keys + * @return static + */ + public function select($keys) + { + if (is_null($keys)) { + return new static($this->items); + } + + if ($keys instanceof Enumerable) { + $keys = $keys->all(); + } + + $keys = is_array($keys) ? $keys : func_get_args(); + + return new static(Arr::select($this->items, $keys)); + } + /** * Get and remove the last N items from the collection. * diff --git a/src/Illuminate/Collections/LazyCollection.php b/src/Illuminate/Collections/LazyCollection.php index e741ba0bf0a0..b3fbb75c0c3d 100644 --- a/src/Illuminate/Collections/LazyCollection.php +++ b/src/Illuminate/Collections/LazyCollection.php @@ -953,6 +953,47 @@ public function only($keys) }); } + /** + * Select specific values from the items within the collection. + * + * @param \Illuminate\Support\Enumerable|array|string $keys + * @return static + */ + public function select($keys) + { + if ($keys instanceof Enumerable) { + $keys = $keys->all(); + } elseif (! is_null($keys)) { + $keys = is_array($keys) ? $keys : func_get_args(); + } + + return new static(function () use ($keys) { + if (is_null($keys)) { + yield from $this; + } else { + foreach ($this as $item) { + $itemKeys = array_flip($keys); + + $result = []; + + foreach ($item as $key => $value) { + if (array_key_exists($key, $itemKeys)) { + $result[$key] = $value; + + unset($itemKeys[$key]); + + if (empty($itemKeys)) { + continue; + } + } + } + + yield $result; + } + } + }); + } + /** * Push all of the given items onto the collection. * diff --git a/tests/Support/SupportCollectionTest.php b/tests/Support/SupportCollectionTest.php index dc82699b9329..e6b02c8dcfed 100755 --- a/tests/Support/SupportCollectionTest.php +++ b/tests/Support/SupportCollectionTest.php @@ -4228,6 +4228,37 @@ public function testOnly($collection) $this->assertEquals(['first' => 'Taylor', 'email' => 'taylorotwell@gmail.com'], $data->only(collect(['first', 'email']))->all()); } + /** + * @dataProvider collectionClassProvider + */ + public function testSelect($collection) + { + $data = new $collection([ + ['first' => 'Taylor', 'last' => 'Otwell', 'email' => 'taylorotwell@gmail.com'], + ['first' => 'Jess', 'last' => 'Archer', 'email' => 'jessarcher@gmail.com'], + ]); + + $this->assertEquals($data->all(), $data->select(null)->all()); + $this->assertEquals([['first' => 'Taylor'], ['first' => 'Jess']], $data->select(['first', 'missing'])->all()); + $this->assertEquals([['first' => 'Taylor'], ['first' => 'Jess']], $data->select('first', 'missing')->all()); + $this->assertEquals([['first' => 'Taylor'], ['first' => 'Jess']], $data->select(collect(['first', 'missing']))->all()); + + $this->assertEquals([ + ['first' => 'Taylor', 'email' => 'taylorotwell@gmail.com'], + ['first' => 'Jess', 'email' => 'jessarcher@gmail.com'], + ], $data->select(['first', 'email'])->all()); + + $this->assertEquals([ + ['first' => 'Taylor', 'email' => 'taylorotwell@gmail.com'], + ['first' => 'Jess', 'email' => 'jessarcher@gmail.com'], + ], $data->select('first', 'email')->all()); + + $this->assertEquals([ + ['first' => 'Taylor', 'email' => 'taylorotwell@gmail.com'], + ['first' => 'Jess', 'email' => 'jessarcher@gmail.com'], + ], $data->select(collect(['first', 'email']))->all()); + } + /** * @dataProvider collectionClassProvider */