Подтвердить что ты не робот

Как использовать значения массива в виде ключей без циклов?

Цикл - это много времени, мы все это знаем. Это то, чего я пытаюсь избежать, хотя и в небольших масштабах. Каждый бит помогает. Ну, если это не удалось, конечно:)

К вопросу

У меня есть массив:

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',
}

Я предполагаю, что это нелегко, но мой разум сейчас разорен, и я не могу думать ни о чем, кроме цикла, чтобы это сделать.

4b9b3361

Ответ 1

Просто используйте array_combine вместе с array_column как

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

Или вы можете просто использовать array_walk, если у вас есть PHP < 5.5 как

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

Отредактировано:

Для будущего пользователя, у которого есть PHP > 5.5, можно просто использовать array_column как

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

Fiddle (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;

Итак, как вывод: простая итерация с простым циклом for является победителем (как упоминалось в этом ответе). На втором месте array_combine разрешено только для новых версий PHP. И в худшем случае я использую собственное решение с закрытием и array_reduce.

Ответ 3

Если у вас есть php >= 5.5:

$res = array_combine(array_column($source, 'id'), array_column($source, 'name'));

Если нет - сделайте цикл.

Ответ 4

Используйте array_map, (PHP 4 >= 4.0.6, PHP 5)

[[email protected] 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);

?>

Выход

[[email protected] 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
)

Ответ 5

Это самый быстрый и простой код здесь до сих пор...

$result = [];
foreach ($input as $subarray) {
    $result[$subarray["id"]] = $subarray["name"];
}

Ответ 6

Попробуйте эту функцию:

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