Re: [PHP-DEV] RFC [Discussion] array_column results grouping

This is only part of a thread. view whole thread
  116568
December 5, 2021 00:50 the.liquid.metal@gmail.com (Hendra Gunawan)
> > 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.