开发者

Replace first level array keys using values from a specific column [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
开发者_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 question

I 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;
});
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜