Skip to content

Commit

Permalink
pluckMany dotted key support (#248)
Browse files Browse the repository at this point in the history
* added dotted tests for PluckMany

* updated CHANGELOG

* Update CHANGELOG.md

---------

Co-authored-by: Freek Van der Herten <[email protected]>
  • Loading branch information
sfinktah and freekmurze authored Jul 2, 2024
1 parent ae721b8 commit 17dca94
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 9 deletions.
24 changes: 15 additions & 9 deletions src/Macros/PluckMany.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

namespace Spatie\CollectionMacros\Macros;

use ArrayAccess;
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;

Expand All @@ -25,21 +24,28 @@ public function __invoke()

return $this->map(function ($item) use ($keys) {
if ($item instanceof Collection) {
if (Arr::accessible($item->all()))
return new static(pluckManyHelper($item->all(), $keys));
return $item->only($keys);
}

if (is_array($item)) {
return Arr::only($item, $keys);
if (Arr::accessible($item)) {
return pluckManyHelper($item, $keys);
}

if ($item instanceof ArrayAccess) {
return collect($keys)->mapWithKeys(function ($key) use ($item) {
return [$key => $item[$key]];
})->toArray();
}
// ArrayAccess handling not required, Arr::accessible includes it.

return (object) Arr::only(get_object_vars($item), $keys);
return (object) pluckManyHelper(get_object_vars($item), $keys);
});
};
}
}

function pluckManyHelper($item, $keys): array {
$result = [];
foreach ($keys as $key) {
if (Arr::has($item, $key))
$result[$key] = Arr::get($item, $key);
}
return $result;
}
36 changes: 36 additions & 0 deletions tests/Macros/PluckManyTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,39 @@
['name' => 'belle', 'hobby' => 'cross-stitch'],
]);
});

it('can pluck dot-notated keys from a collection of collections', function () {
$data = Collection::make([
collect(['id' => 1, 'name' => 'matt', 'info' => ['hobby' => 'coding']]),
collect(['id' => 2, 'name' => 'tomo', 'info' => ['hobby' => 'cooking']]),
]);

expect($data->pluckMany(['name', 'info.hobby']))->toEqual(collect([
collect(['name' => 'matt', 'info.hobby' => 'coding']),
collect(['name' => 'tomo', 'info.hobby' => 'cooking'])
]));
});

it('can pluck dot-notated keys from array and object items', function () {
$data = Collection::make([
(object) ['id' => 1, 'name' => 'matt', 'info' => ['hobby' => 'coding']],
['id' => 2, 'name' => 'tomo', 'info' => ['hobby' => 'cooking']],
]);

expect($data->pluckMany(['name', 'info.hobby'])->all())->toEqual([
(object) ['name' => 'matt', 'info.hobby' => 'coding'],
['name' => 'tomo', 'info.hobby' => 'cooking'],
]);
});

it('can pluck dot-notated keys from objects that implement array access interface', function () {
$data = Collection::make([
new TestArrayAccessImplementation(['id' => 1, 'name' => 'marco', 'info' => ['hobby' => 'drinking']]),
new TestArrayAccessImplementation(['id' => 2, 'name' => 'belle', 'info' => ['hobby' => 'cross-stitch']]),
]);

expect($data->pluckMany(['name', 'info.hobby'])->all())->toEqual([
['name' => 'marco', 'info.hobby' => 'drinking'],
['name' => 'belle', 'info.hobby' => 'cross-stitch'],
]);
});

0 comments on commit 17dca94

Please sign in to comment.