如何在没有循环的情况下使用数组值作为键?

2022-08-30 17:37:01

循环是耗时的,我们都知道这一点。这正是我试图避免的事情,即使它的规模很小。每一点都有帮助。好吧,如果它没有设置当然:)

关于问题

我有一个数组:

array(3) {
    '0' => array(2) {
        'id'   => 1234,
        'name' => 'blablabla',
    },
    '1' => array(2) {
        'id'   => 1235,
        'name' => 'ababkjkj',
    },
    '2' => array(2) {
        'id'   => 1236,
        'name' => 'xyzxyzxyz',
    },
}

我正在尝试做的是按如下方式转换此数组:

array(3) {
    '1234' => 'blablabla',
    '1235' => 'asdkjrker',
    '1236' => 'xyzxyzxyz',
}

我想这不是一件很难的事情,但我的头脑现在已经崩溃了,除了循环来完成这项工作之外,我想不出任何事情。


答案 1

只需与 as 一起使用即可array_combinearray_column

array_combine(array_column($array,'id'), array_column($array,'name'));

或者,如果您有 PHP < 5.5,则可以简单地将其用作array_walk

$result = array();
array_walk($array, function($v)use(&$result) {
    $result[$v['id']] = $v['name']; 
});

编辑:

对于拥有PHP>5.5的未来用户可以简单地使用array_column

array_column($array,'name','id');

小提琴(array_walk)


答案 2

UPD警告最慢的解决方案!请参阅下面的基准测试。

试试这个代码:

$a = array(array('id'   => 1234,
                 'name' => 'blablabla'),
           array('id'   => 1235,
                 'name' => 'ababkjkj'),
           array('id'   => 1236, 
                 'name' => 'xyzxyzxyz'));

var_export(array_reduce($a, function($res, $item) {
    $res[$item['id']] = $item['name'];
    return $res;
}));

即使在 PHP 5.3 中也能正常工作。并且只使用一个函数。array_reduce

UPD:以下是一些基准测试(PHP 5.6 在中等质量服务器上的 Debian 7 之上):

$a = [];
for ($i = 0; $i < 150000; $i++) {
    $a[$i] = ['id' => $i,
               'name' => str_shuffle('abcde') . str_shuffle('01234')];
}

$start = microtime(true);

if (false) {
    // 7.7489550113678 secs for 15 000 itmes
    $r = array_reduce($a, function($res, $item) {
             $res[$item['id']] = $item['name'];
             return $res;
         });
}

if (false) {
    // 0.096649885177612 secs for 150 000 items
    $r = array_combine(array_column($a, 'id'),
                       array_column($a, 'name'));
}

if (true) {
    // 0.066264867782593 secs for 150 000 items
    $r = [];
    foreach ($a as $subarray) {
        $r[$subarray['id']] = $subarray['name'];
    }
}

if (false) {
    // 0.32427287101746 secs for 150 000 items
    $r = [];
    array_walk($a, function($v) use (&$r) {
        $r[$v['id']] = $v['name'];
    });
}

echo (microtime(true) - $start)  . ' secs' . PHP_EOL;

因此,作为结论:具有简单循环的简单迭代赢家(如本答案中所述)。在第二个地方,只允许新版本的PHP。最糟糕的情况是使用我自己的解决方案,闭包和.forarray_combinearray_reduce