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

Pet*_*ter 22 php arrays multidimensional-array

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

关于这个问题

我有一个数组:

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

我要做的是将此数组转换如下:

array(3) {
    '1234' => 'blablabla',
    '1235' => 'asdkjrker',
    '1236' => 'xyzxyzxyz',
}
Run Code Online (Sandbox Code Playgroud)

我想这不是一件很难的事情,但我的思绪现在已被破坏,除了循环以完成任务之外我什么也想不到.

Nar*_*dia 26

只需array_combinearray_columnas 一起使用即可

array_combine(array_column($array,'id'), array_column($array,'name'));
Run Code Online (Sandbox Code Playgroud)

或者你可以简单地使用,array_walk如果你有PHP <5.5

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

编辑:

对于PHP> 5.5的未来用户,可以简单地使用array_columnas

array_column($array,'name','id');
Run Code Online (Sandbox Code Playgroud)

小提琴(array_walk)

  • 虽然这是一个相当古老的问题,但我只是偶然发现它.简单地说`array_column($ input,'name','id')`将产生相同的输出(参考:[`index_key`](https://php.net/manual/function.array-column.php)). (2认同)
  • `array_walk`仍然是一个循环,它是一个迭代器,就像一个`for`(你定义基于整数的迭代系统)或`foreach`(它是一次迭代迭代系统迭代的基本键),但是其他方法使用迭代器,它只是你想要多少编译代码与脚本代码相比:) (2认同)

Iva*_*hko 8

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;
}));
Run Code Online (Sandbox Code Playgroud)

即使在PHP 5.3中也能正常工作.并且只使用一个功能array_reduce.

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

$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;
Run Code Online (Sandbox Code Playgroud)

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


u_m*_*der 7

如果你有php> = 5.5:

$res = array_combine(array_column($source, 'id'), array_column($source, 'name'));
Run Code Online (Sandbox Code Playgroud)

如果不是 - 做一个循环.

  • 它的性感,但在某个地方正在循环 (3认同)
  • 这可能是3个循环而不是1个循环!如果你真的考虑过它.不可否认,这将是一个`C`代码执行循环,但3x`c`循环运行速度比1x`php`循环快 (2认同)