Replace first level array keys using values from a specific column [closed]
开发者_StackOverflow社区
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 12 months ago.
Improve this questionI have an array like this
$users = array(
[0] => array('Id' => 3, 'Name' => 'Bob'),
[1] => array('Id' => 8, 'Name' => 'Alice'),
)
and I want to pull the Ids 'up' one level so that the final array is:
$usersById = array(
[3] => array('Id' => 3, 'Name' => 'Bob'),
[8] => array('Id' => 8, 'Name' => 'Alice'),
)
The Id values are unique.
Is there a native PHP way to do this? The code I'm currently using is:
$usersById = array();
foreach ($users as $key => $value)
{
$usersById[$value['Id']] = $value;
}
This works, but is not terribly elegant.
Modern answer (requires PHP 5.5)
The new function array_column
is very versatile and one of the things it can do is exactly this type of reindexing:
// second parameter is null means we 're just going to reindex the input
$usersById = array_column($users, null, 'Id');
Original answer (for earlier PHP versions)
You need to fetch the ids from the sub-arrays with array_map
, then create a new array with array_combine
:
$ids = array_map(function($user) { return $user['Id']; }, $users);
$users = array_combine($ids, $users);
The code above requires PHP >= 5.3 for the anonymous function syntax, but you can also do the same (albeit it will look a bit uglier) with create_function
which only requires PHP >= 4.0.1:
$ids = array_map(create_function('$user', 'return $user["Id"];'), $users);
$users = array_combine($ids, $users);
See it in action.
You could use the array_reduce()
function, like:
$usersById = array_reduce($users, function ($reduced, $current) {
$reduced[$current['Id']] = $current;
return $reduced;
});
However, it's no more elegant than a foreach
.
I think using foreach
is much more elegant. Maybe you just only want to write it differently:
$keyed = array();
foreach($users as $w) $keyed[$w['Id']] = $w;
In case you want to replace the existing array, foreach
is not that flexible indeed. But maybe the following is some sort of alternative:
$users = function($key) use ($users)
{
foreach($users as $v) $keys[] = $v[$key];
return array_combine($keys, $users);
};
$users = $users('Id');
It allows the callback to accept parameters, e.g. the name of the key which should be used to create the new keys from.
And one more variant using array_walk:
$usersById = array();
array_walk($users, function($val) use (&$usersById) {
$usersById[$val['Id']] = $val;
});
精彩评论