使用平面数组的值生成关联数组,其键和值都被赋予静态前缀

问题描述 投票:0回答:4

以下代码有简写吗:

$result = array_combine(
    array_map(fn($elem) => "key_$elem", $array), 
    array_map(fn($elem) => "value_$elem", $array)
);

PHP 沙箱

我不喜欢这样的想法(从可读性的角度来看):必须在同一个数组上使用数组映射两次,然后组合中间结果。

php arrays associative-array array-map array-combine
4个回答
1
投票

您可以使用

array_reduce

https://www.php.net/manual/en/function.array-reduce.php

$result = array_reduce($array, fn ($carry, $item) => $carry + ["key_$item" => "value_$item"], []);

PHP 沙箱


1
投票

我只是定义简单的函数,就像这样:

function array2map($a) {
    $r = []; foreach ($a as $v) $r['key_'.$v] = 'value_'.$v; return $r;
}

$result = array2map($array);

0
投票

感谢您的建议。不过,我已经找到了一个我更喜欢的解决方案:

$result = array_merge(...array_map(fn($elem) => ["key_$elem" => "value_$elem"], $array));

PHP 沙箱


0
投票

我发现这个人为的任务相当不现实(作为一个真实的单词用例是深不可测的)。代码样式的偏好取决于个人喜好。

如果我们要考虑学术向量的选择,那么我们不仅应该比较代码的简洁性,还应该比较时间复杂性、直接性、最小化函数调用,甚至可能还应该比较内存。

TL;博士:

  1. 经典语言构造迭代(如

    foreach()
    )将始终优于函数迭代器。使用生成器可以极大地进一步提高性能和内存消耗。

  2. 所有其他函数迭代器的执行时间都足够接近,您可能不应该浪费开发时间来考虑哪个迭代器最快。

  3. 在我测试的所有方法中,只有

    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的代码片段——它干净、直接、函数式,并且不需要进行多次迭代。

如果我有速度或内存问题,我会使用发电机。

© www.soinside.com 2019 - 2024. All rights reserved.