Re: RFC [Discussion] array_column results grouping

From: Date: Sun, 05 Dec 2021 00:50:41 +0000
Subject: Re: RFC [Discussion] array_column results grouping
References: 1  Groups: php.internals 
Request: Send a blank email to internals+get-116568@lists.php.net to get a copy of this message
> > Hello, this is a proposal to upgrade the functionality of > array_column to return an indexed array for all of the matched > data > instead of a single result. > > the RFC had been created here > https://wiki.php.net/rfc/array_column_results_grouping and the > PR is > in here https://github.com/php/php-src/pull/7698. > > However, I am not sure, if we need to add a fourth parameter to the > function to change its behavior or we can add it as a new function, > something like array_column_group or any other name. > Hai Hassan. It seems that your proposal is just save no more than 3 lines compared with foreach. Moreover, foreach can do better than your version. foreach ($persons as $p) { $groups[$p["education"]][$p["sex"]][MORE_SUBGRUP][] = $p; } output: $groups = [ "elementary" => [ "female" => [ MORE_SUBGRUP_1 => [ 0 => [...], 1 => [...] ], MORE_SUBGRUP_2 => [ 0 => [...], 1 => [...] ], ... ], "male" => [ MORE_SUBGRUP_1 => [ 0 => [...], 1 => [...] ], MORE_SUBGRUP_2 => [ 0 => [...], 1 => [...] ], ... ], ], "highschool" => [ ... ], ... ]; my suggestions are: - don't limit to array => involve object as well - offer reducer callable as an optional last param. reducer callable it will transform 2 steps algo (populating the groups and then reducing) to become a single step. but if it is not provided, the function returns the member of the group (same as example above). old way: // step-1 $group = []; foreach ($persons as $p) {/*...*/} // step-2 foreach ($group as &$eduGroup) { foreach ($eduGroup as &$sexGroup) { $sumWeight = 0; foreach ($sexGroup as $item) { $sumWeight += $item->weight; } $sexGroup = $sumWeight / count($sexGroup); } } output: $groups = [ "elementary" => [ "female" => 40, "male" => 50, ], "highschool" => [ "female" => 60, "male" => 65, ], ... ]; new way: array_column_group( $group, ["education", "sex", MORE_SUBGRUP], fn ($item, $i, $cumm) => ($item->weight + ($cumm * $i)) / ($i + 1) ); the signature: // array_column_group signature array_column_group( array|object $array, int|string|array $index_key, callable $reducer = null ) // callable signature fn (array|object $item, int|string $index, mixed $cummulative): mixed note: - $index_key can be in the form ["education", ...] or "education". - or even [0, 1, ...] or 0. So virtually, array_column_group is a hybrid between array_column and array_walk (or other function with a funny name which I don't remember). Best Regards Hendra Gunawan.

« previous php.internals (#116568) next »