Цикл – это много времени, мы все это знаем. Это то, чего я пытаюсь избежать, хотя это в небольшом масштабе. Каждый бит помогает. Ну, если это неудивительно, конечно 🙂
У меня есть массив:
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', }
Я предполагаю, что это нелегко, но мой разум сейчас разорен, и я не могу думать ни о чем, кроме цикла, чтобы это сделать.
Просто используйте array_combine
вместе с array_column
как
array_combine(array_column($array,'id'), array_column($array,'name'));
Или вы можете просто использовать array_walk
если у вас есть PHP <5.5 as
$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)
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;
Итак, как вывод: победитель (как упоминалось в этом ответе ) – простая итерация с простым циклом. На втором месте array_combine
допускается только для новых версий PHP. И худший случай – использование моего собственного решения с закрытием и array_reduce
.
Если у вас есть php> = 5.5:
$res = array_combine(array_column($source, 'id'), array_column($source, 'name'));
Если нет – сделайте цикл.
Используйте функцию array_map , (PHP 4> = 4.0.6, PHP 5)
[akshay@localhost tmp]$ cat test.php <?php $array = array( array('id' => 1234,'name' => 'blablabla'), array('id' => 1235,'name' => 'ababkjkj'), array('id' => 1236,'name' => 'xyzxyzxyz') ); $output = array(); array_map(function($_) use (&$output){ $output[$_['id']] = $_['name']; },$array); // Input print_r($array); // Output print_r($output); ?>
Вывод
[akshay@localhost tmp]$ php test.php Array ( [0] => Array ( [id] => 1234 [name] => blablabla ) [1] => Array ( [id] => 1235 [name] => ababkjkj ) [2] => Array ( [id] => 1236 [name] => xyzxyzxyz ) ) Array ( [1234] => blablabla [1235] => ababkjkj [1236] => xyzxyzxyz )
Это самый быстрый и простой код здесь до сих пор …
$result = []; foreach ($input as $subarray) { $result[$subarray["id"]] = $subarray["name"]; }
Попробуйте эту функцию:
array_combine(array_column($array,'id'), array_column($array,'name'));