以下代码有简写吗:
$result = array_combine(
array_map(fn($elem) => "key_$elem", $array),
array_map(fn($elem) => "value_$elem", $array)
);
我不喜欢这样的想法(从可读性的角度来看):必须在同一个数组上使用数组映射两次,然后组合中间结果。
您可以使用
array_reduce
https://www.php.net/manual/en/function.array-reduce.php
$result = array_reduce($array, fn ($carry, $item) => $carry + ["key_$item" => "value_$item"], []);
我只是定义简单的函数,就像这样:
function array2map($a) {
$r = []; foreach ($a as $v) $r['key_'.$v] = 'value_'.$v; return $r;
}
$result = array2map($array);
感谢您的建议。不过,我已经找到了一个我更喜欢的解决方案:
$result = array_merge(...array_map(fn($elem) => ["key_$elem" => "value_$elem"], $array));
我发现这个人为的任务相当不现实(作为一个真实的单词用例是深不可测的)。代码样式的偏好取决于个人喜好。
如果我们要考虑学术向量的选择,那么我们不仅应该比较代码的简洁性,还应该比较时间复杂性、直接性、最小化函数调用,甚至可能还应该比较内存。
TL;博士:
经典语言构造迭代(如
foreach()
)将始终优于函数迭代器。使用生成器可以极大地进一步提高性能和内存消耗。
所有其他函数迭代器的执行时间都足够接近,您可能不应该浪费开发时间来考虑哪个迭代器最快。
在我测试的所有方法中,只有
array_reduce()
遇到了灾难性的内存问题。经过研究,我发现使用 ArrayObject 将克服底层内存挑战(当你不能简单地增加内存限额时)。
现在我将列出从这个早期答案到一个非常相似的问题的不同方法,我通过更多方法对其进行了调整和扩展。
发电机带
foreach()
function generate($array) { // 1 loop over data
foreach ($array as $v) {
yield 'key' . $v => 'value' . $v;
}
}
function generator($array) { // 1 parent loop over data
return iterator_to_array(generate($array));
}
普通的
foreach()
循环:
function construct($array) { // 1 loop over data
$result = [];
foreach ($array as $v) {
$result['key' . $v] = 'value' . $v;
}
return $result;
}
array_combine()
带有两个嵌套 array_map()
调用:
function mapCombine($array) { // 3 loops over data
return array_combine(
array_map(
fn($v) => 'key' . $v,
$array
),
array_map(
fn($v) => 'value' . $v,
$array
),
);
}
展平二维数组:
function mapFlatten($array) { // 3 loops over data
return array_merge(
...array_map(
fn($v) => ['key' . $v => 'value' . $v],
$array
),
);
}
将二维数组转换为关联数组
array_column()
:
function mapUncolumn($array) { // 2 loops over data
return array_column(
array_map(
fn($v) => ['key' . $v, 'value' . $v],
$array
),
1,
0
);
}
array_walk()
带有参考数组:
function walk($array) { // 1 loop over data
$result = [];
array_walk(
$array,
function($v) use (&$result) {
$result['key' . $v] = 'value' . $v;
}
);
return $result;
}
array_reduce()
专为处理大型有效负载而设计:
function reduce($array) { // 1 loop over data
return array_reduce(
$array,
function($result, $v) {
$result['key' . $v] = 'value' . $v;
return $result;
},
new ArrayObject()
);
}
我的测试脚本:(Demo)
function returnTime(callable $function, int $repeat = 20)
{
$tests = [];
for ($i = 0; $i < $repeat; ++$i) {
$startTime = microtime(true);
$function();
$endTime = microtime(true);
$tests[] = $endTime - $startTime;
}
// Representing the average
return 1000 * array_sum($tests) / $repeat;
}
$array = range(0, 5000);
foreach (['generate', 'construct', 'mapCombine', 'mapFlatten', 'mapUncolumn', 'walk', 'reduce'] as $test) {
echo "Duration of $test: ", returnTime(fn() => $test($array)) . PHP_EOL;
}
结果:
Duration of generate: 0.00071525573730469
Duration of construct: 0.8031964302063
Duration of mapCombine: 1.0213017463684
Duration of mapFlatten: 1.219916343689
Duration of mapUncolumn: 1.3207793235779
Duration of walk: 1.2843608856201
Duration of reduce: 1.0416030883789
如果我需要在专业应用程序中执行这样的流程,我可能会使用@User863的代码片段——它干净、直接、函数式,并且不需要进行多次迭代。
如果我有速度或内存问题,我会使用发电机。