PHP массив сводится к ключу подмассива - PullRequest
6 голосов
/ 17 сентября 2011

У меня есть такой массив

$users = array(
    [0] => array('Id' => 3, 'Name' => 'Bob'),
    [1] => array('Id' => 8, 'Name' => 'Alice'),
)

, и я хочу вытащить идентификаторы на один уровень вверх, чтобы окончательный массив был:

$usersById = array(
    [3] => array('Id' => 3, 'Name' => 'Bob'),
    [8] => array('Id' => 8, 'Name' => 'Alice'),
)

Значения идентификатора:уникальный.

Есть ли собственный способ PHP сделать это?Код, который я сейчас использую:

$usersById = array();
foreach ($users as $key => $value)
{
    $usersById[$value['Id']] = $value;
}

Это работает, но не очень элегантно.Спасибо!

Ответы [ 5 ]

17 голосов
/ 17 сентября 2011

Современный ответ (требуется PHP 5.5)

Новая функция array_column очень универсальна, и одна из вещей, которую она может сделать, это именно такой тип переиндексации:

// second parameter is null means we 're just going to reindex the input
$usersById = array_column($users, null, 'Id');

Исходный ответ (для более ранних версий PHP)

Вам нужно извлечь идентификаторы из подмассивов с помощью array_map, а затем создать новый массив с array_combine:

$ids = array_map(function($user) { return $user['Id']; }, $users);
$users = array_combine($ids, $users);

Приведенный выше код требует PHP> = 5.3 для синтаксиса анонимной функции, но вы также можете сделать то же самое (хотя это будет выглядеть немного уродливее) с create_function, для которого требуется только PHP> = 4.0.1:

$ids = array_map(create_function('$user', 'return $user["Id"];'), $users);
$users = array_combine($ids, $users);

См. Это в действии .

10 голосов
/ 17 сентября 2011

Вы можете использовать функцию array_reduce(), например:

$usersById = array_reduce($users, function ($reduced, $current) {
    $reduced[$current['Id']] = $current;
    return $reduced;
});

Однако это не более элегантно, чем foreach.

2 голосов
/ 18 сентября 2011

Я думаю, что использование foreach намного элегантнее. Может быть, вы просто хотите написать это по-другому:

$keyed = array();
foreach($users as $w) $keyed[$w['Id']] = $w;

Если вы хотите заменить существующий массив, foreach на самом деле не так уж и гибок. Но, может быть, следующая альтернатива:

$users = function($key) use ($users)
{
    foreach($users as $v) $keys[] = $v[$key];
    return array_combine($keys, $users);
};
$users = $users('Id');

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

1 голос
/ 17 сентября 2011

И еще один вариант с использованием array_walk:

$usersById = array();
array_walk($users, function($val) use (&$usersById) {
    $usersById[$val['Id']] = $val;
});
0 голосов
/ 17 сентября 2011
 $usersById = array_combine(array_keys($users), array_values($users));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...