使用特定列中的值替换第一级数组键


Replace first level array keys using values from a specific column

我有一个像这样的数组

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

,我想把id '向上'拉一级,这样最后的数组是:

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

Id值是唯一的。

是否有一个本地的PHP方法来做到这一点?我目前使用的代码是:

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

现代答案(需要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的子数组中获取id,然后创建包含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);

查看效果

您可以使用array_reduce()函数,如:

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

然而,它并不比foreach更优雅。

我认为使用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');

它允许回调接受参数,例如,应该用来创建新密钥的密钥的名称。

还有一个变体使用array_walk:

$usersById = array();
array_walk($users, function($val) use (&$usersById) {
    $usersById[$val['Id']] = $val;
});