Allow ArrayCollection#filter to filter by key, value or both
Opened this issue · 5 comments
Scenario
I want be able to filter an array by key or both (key, value)
/// DOESN"T WORK :(
(new ArrayCollection(['italian' => 'pizza', 'turkish' => 'kebab']))
->filter(function($k, $v) {
return 'turkish' === $k;
})
// WORKSS!1!!
array_filter(['italian' => 'pizza', 'turkish' => 'kebab'], function($k, $v) {
return 'turkish' === $k;
}, ARRAY_FILTER_USE_BOTH);
Suggested Solution
Since PHP 5.6 we are able to specify a flag on array_filter
which allows to filter the element of the array by passing to the closure that filter the array, key, value or both
array array_filter ( array $array [, callable $callback [, int $flag = 0 ]] )
Flag determining what arguments are sent to callback:
ARRAY_FILTER_USE_KEY - pass key as the only argument to callback instead of the value
ARRAY_FILTER_USE_BOTH - pass both value and key as arguments to callback instead of the value
Default is 0 which will pass value as the only argument to callback instead.
Suggested Implementation
At the moment ArrayCollection#filter uses the default value 0 which makes the flag feature impossible to use.
- public function filter(Closure $p)
+ public function filter(Closure $p, int $flag = 0)
{
- return $this->createFrom(array_filter($this->elements, $p));
+ return $this->createFrom(array_filter($this->elements, $p, $flag));
}
Concerns
I understand that exposing lower level APIs to an higher level of abstraction is not probably a good idea. Yet, the additional feature would be useful overall to the client who uses the method
If you provide some feedback I can submit a PR
@0x13A if this can be implemented without introducing a BC break, I'd say "why not"?
Also, a benchmark is required here, due to this being performance-sensitive API for downstream consumers.
@Ocramius Thanks for the reply.
Using the default value for $flag = 0
does not introduce a BC Break as it is the default behaviour of array_filter. I will update this issue as soon as I have a PR.
@0x13A I'm suggesting to use the ARRAY_FILTER_USE_BOTH
as default, whilst keeping the public API of the method unchanged.
That makes a lot of sense