patternphpMinor
Generic array group by using lambda
Viewed 0 times
genericgrouparrayusinglambda
Problem
This is K.I.S.S, but how about some error and misuse control? I am wishing it were .NET.
Solution
- Using the
[]syntax for adding array items, allows PHP to create the array as necessary. Thus you can scrap theifstatement for a modest performance increase off 10 to 15% in my own testing. (Unlike if you usedarray_push()which would throw a warning instead.
-
The unused
$group variable appears to be a mistake, as the function appears to fulfill it's purpose without it. Code reduced to:function array_group_by($arr, $key_selector) {
$result = array();
foreach ($arr as $i) {
$key = $key_selector($i);
$result[$key][] = $i;
}
return $result;
}- At this point, the
$keycould also be left out, but it's almost free in terms of performance, and increases readability, so I left it there.
-
I'm not sure how much misuse and error handling you need, the function is pretty simple. I would stick with type-hinting the arguments.
array is available since PHP 5.1, callable since 5.4. The signature would becomefunction array_group_by(array $arr, callable $key_selector);Then PHP will at run-time throw a fatal error at anyone trying to call the function with incorrect parameters. Generally I think that's good, but in this particular case, it introduces a problem.
array('class_A', 'method_B'), is a valid callable, that won't work with with the fast $function($arg);. For any valid callable to get executed, you need to use call_user_func() instead, which is a bit slower. In my testing however, the removal of the if has bigger impact than the use of call_user_func(), so if this isn't performance critical, stick with callable and call_user_func().Final code:
function array_group_by(array $arr, callable $key_selector) {
$result = array();
foreach ($arr as $i) {
$key = call_user_func($key_selector, $i);
$result[$key][] = $i;
}
return $result;
}Code Snippets
function array_group_by($arr, $key_selector) {
$result = array();
foreach ($arr as $i) {
$key = $key_selector($i);
$result[$key][] = $i;
}
return $result;
}function array_group_by(array $arr, callable $key_selector);function array_group_by(array $arr, callable $key_selector) {
$result = array();
foreach ($arr as $i) {
$key = call_user_func($key_selector, $i);
$result[$key][] = $i;
}
return $result;
}Context
StackExchange Code Review Q#23919, answer score: 4
Revisions (0)
No revisions yet.