Re: RFC karma request: array_partition()
| From: | Ayoub EZZINI | Date: | Sat, 24 Oct 2026 00:19:33 +0000 |
| Subject: | Re: RFC karma request: array_partition() | ||
| References: | 1 2 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-132910@lists.php.net to get a copy of this message | ||
Hi,
Thanks for the support and the detailed feedback!
> - Semantically, the function name affords an indefinite number of
> groups/partitions.
[...]
> - Was strictly partitioning into only two parts a deliberate intention
> specific to the term "partition"?
Yes, it was deliberate. In the languages and libraries PHP developers
are most likely to know, "partition" means a split by a boolean
predicate into exactly two parts: Ruby's Enumerable#partition, Kotlin's
partition, Rust's Iterator::partition, Haskell's Data.List.partition and
Laravel's Collection::partition. Each of them also ships grouping as a
separate function (group_by, groupBy, ...). I'd like PHP to follow the
same split, so that array_partition() does what people coming from
those ecosystems expect.
> - I want to be able to make unlimited groups keyed by the callback's
> return value
That's a useful function too, but I think it's a different one. There
is an existing draft RFC for exactly that, array_group() by Boro
Sitnikovski (https://wiki.php.net/rfc/array_group, 2023), which never
went to a vote. I'd be happy to see it revived, and the two would
complement each other.
Using a general grouping function for the two-way case is also less
convenient: the bucket keys come from the callback's return value, and
a bucket is missing entirely when nothing falls into it. You'd write:
$groups = array_group($users, fn($u) => $u->age >= 18 ? 'adult' :
'minor');
$adults = $groups['adult'] ?? [];
$minors = $groups['minor'] ?? [];
whereas array_partition() always returns both parts, so destructuring
always works:
[$adults, $minors] = array_partition($users, fn($u) => $u->age >= 18);
> - It feels unintuitive that
true callback outcomes map to the
> 0 key
> and false outcomes map to 1.
The result is meant to be read as a pair rather than a map from boolean
to bucket, and "matching first" is the order used by all of the
functions above. With destructuring, the names carry the meaning:
[$matching, $rest].
> - The callback should have access to the arrays keys and values.
Agreed, and this is already done: following review on the PR, the
callback now receives ($value, $key), like array_find() and friends,
and the $mode parameter is gone:
function array_partition(array $array, callable $callback): array
https://github.com/php/php-src/pull/24568
I'll cover the naming and the relationship to array_group() in the RFC.
Thanks,
Ayoub
On Fri, Oct 23, 2026 at 11:16 PM mickmackusa <mickmackusa@gmail.com> wrote:
>
> Hi Ayoub,
>
> I am in support of array_partition() being added to the
> language in some way. Here is my feedback:
>
> - Semantically, the function name affords an indefinite number of groups/partitions. I have had
> many use cases where more than two partitions are desired.
> - It feels unintuitive that true callback outcomes map to the
> 0 key and false outcomes map to
> 1.
> - I want to be able to make unlimited groups keyed by the callback's return value (so long
> as the return value is a string or an int).
> $ageGrouped = array_partition($users, fn($u) => $u->age ??
> -1);
> $byFirstByte = array_partition($words, fn($word) => substr($word, 0,
> 1));
> - The callback should have access to the arrays keys and values.
> $modulusGrouped = array_partition($rows, fn($row, $i) => $i %
> 7);
> - Allowing your original intention of an indexed array with true outcomes first is still
> afforded by tweaking the evaluation or merely negating the boolean outcomes with
> !(expression).
> - Was strictly partitioning into only two parts a deliberate intention specific to the the term
> "partition"? I mean, did you deliberately choose to not name the function
> array_group()/array_batch() which
> might align with my behavioral deviation?
>
> Good luck with the RFC.
>
> mickmackusa