用给定的相应密钥替换数组密钥


replace array keys with given respective keys

我有一个类似的数组

$old = array(
       'a' => 'blah',
       'b' => 'key',
       'c' => 'amazing',
       'd' => array(
                0 => 'want to replace',
                1 => 'yes I want to'
              )
       );

我有另一个数组,其中包含要替换为密钥信息的密钥。

$keyReplaceInfoz = array('a' => 'newA', 'b' => 'newB', 'c' => 'newC', 'd' => 'newD');

我需要将数组$old的所有密钥替换为数组$keyReplaceInfo中的相应值。

输出应该像这个

$old = array(
       'newA' => 'blah',
       'newB' => 'key',
       'newC' => 'amazing',
       'newD' => array(
                0 => 'want to replace',
                1 => 'yes I want to'
              )
       );

我必须手动完成,如下所示。我期待更好的选择。有人能提出更好的方法来实现这一点吗?

$new = array();
foreach ($old as $key => $value)
{
     $new[$keyReplaceInfoz[$key]] = $value;
}

我知道这可以更简单。

array_combine(array_merge($old, $keyReplaceInfoz), $old)

我觉得这看起来比你摆的姿势更简单。

array_combine(
    ['newKey1', 'newKey2', 'newKey3'],
    array_values(['oldKey1' => 1, 'oldKey2' => 2, 'oldKey3' => 3])
);

只要你有相同数量的值和相同的顺序,这就可以了。

IMO使用array_component、array_merge,甚至array_entersect_key都是过度使用。原始代码足够好,而且速度非常快。

适应@shawn-k解决方案,这里有更干净的代码使用array_walk,它只会替换所需的密钥,当然你可以根据自己的方便修改

array_walk($old, function($value,$key)use ($keyReplaceInfoz,&$old){
        $newkey = array_key_exists($key,$keyReplaceInfoz)?$keyReplaceInfoz[$key]:false;
        if($newkey!==false){$old[$newkey] = $value;unset($old[$key]);
        }
    });
    print_r($old);

我刚刚在自己的应用程序中解决了同样的问题,但对于我的应用程序,$keyReplaceInfoz就像白名单一样——如果找不到键,那么整个元素将从结果数组中删除,而匹配的白名单键将被转换为新值。

我想你可以通过巧妙地使用array_map来应用同样的算法,也许总代码更少(http://php.net/manual/en/function.array-map.php),也许另一位慷慨的读者会这么做。

function filterOldToAllowedNew($key_to_test){       
    return isset($keyReplaceInfoz[$key_to_test])?$keyReplaceInfoz[$key_to_test]:false;
}   
$newArray = array();
foreach($old as $key => $value){
    $newkey = filterOldToAllowedNew($key);
    if($newkey){
       $newArray[$newkey] = $value;
    }
}
print_r($newArray);

这个问题很老,但由于它首先出现在谷歌上,我想我应该添加解决方案。

// Subject
$old = array('foo' => 1, 'baz' => 2, 'bar' => 3));
// Translations    
$tr  = array('foo'=>'FOO', 'bar'=>'BAR');
// Get result
$new = array_combine(preg_replace(array_map(function($s){return "/^$s$/";}, 
           array_keys($tr)),$tr, array_keys($old)), $old);
// Output
print_r($new);

结果:

大堆([FOO]=>1[baz]=>2[BAR]=>3)

这是我为同一主题实现的解决方案:

/**
 * Replace keys of given array by values of $keys
 * $keys format is [$oldKey=>$newKey]
 *
 * With $filter==true, will remove elements with key not in $keys
 *
 * @param  array   $array
 * @param  array   $keys
 * @param  boolean $filter
 *
 * @return $array
 */
function array_replace_keys(array $array,array $keys,$filter=false)
{
    $newArray=[];
    foreach($array as $key=>$value)
    {
        if(isset($keys[$key]))
        {
            $newArray[$keys[$key]]=$value;
        }
        elseif(!$filter)
        {
            $newArray[$key]=$value;
        }
    }
    return $newArray;
}

这与数组顺序无关;数组计数。输出顺序&值将基于replaceKey。

$replaceKey = array('a' => 'newA', 'b' => 'newB', 'c' => 'newC', 'd' => 'newD', 'e' => 'newE','f'=>'newF');
$array = array(
       'a' => 'blah',
       'd' => array(
                0 => 'want to replace',
                1 => 'yes I want to'
              ),
       'noKey'=>'RESIDUAL',
       'c' => 'amazing',
       'b' => 'key',
       );
$filterKey = array_intersect_key($replaceKey,$array);
$filterarray = array_intersect_key(array_merge($filterKey,$array),$filterKey);
$replaced = array_combine($filterKey,$filterarray);
//output
var_export($replaced);
//array ( 'newA' => 'blah', 'newB' => 'key', 'newC' => 'amazing', 'newD' => array ( 0 => 'want to replace', 1 => 'yes I want to' ) )

如果您正在寻找一个用于多维数组的递归解决方案,请查看以下方法。它将替换所有请求的密钥,并保留所有其他密钥。

/**
 * Given an array and a set of `old => new` keys,
 * will recursively replace all array keys that
 * are old with their corresponding new value.
 *
 * @param mixed $array
 * @param array $old_to_new_keys
 *
 * @return array
 */
function array_replace_keys($array, array $old_to_new_keys)
{
    if(!is_array($array)){
        return $array;
    }
    $temp_array = [];
    $ak = array_keys($old_to_new_keys);
    $av = array_values($old_to_new_keys);
    foreach($array as $key => $value){
        if(array_search($key, $ak, true) !== false){
            $key = $av[array_search($key, $ak)];
        }
        if(is_array($value)){
            $value = array_replace_keys($value, $old_to_new_keys);
        }
        $temp_array[$key] = $value;
    }
    return $temp_array;
}

使用OP的示例阵列:

$old = array(
       'a' => 'blah',
       'b' => 'key',
       'c' => 'amazing',
       'd' => array(
                0 => 'want to replace',
                1 => 'yes I want to'
              )
       );
$replace = ["a" => "AA", 1 => 11];
var_export(array_replace_keys($old, $replace));

给出以下输出:

array (
  'AA' => 'blah',
  'b' => 'key',
  'c' => 'amazing',
  'd' => 
  array (
    0 => 'want to replace',
    11 => 'yes I want to',
  ),
)

演示

灵感来自以下片段。

这使用了@Summoner的例子,但记住了@Leigh的提示:

$start = microtime();
$array = [ "a" => 1, "b" => 2, "c" => 3 ];
function array_replace_key($array, $oldKey, $newKey) {
    $keys = array_keys($array);
    $idx = array_search($oldKey, $keys);
    array_splice($keys, $idx, 1, $newKey);
    return array_combine($keys, array_values($array));
}
print_r(array_replace_key($array, "b", "z"));
    <?php
$new = array(); 
foreach ($old as $key => $value)
{
     $new[$keyReplaceInfoz][$key] = $value;
}
?>