18

我该怎么做:

$array = array('a' => 1, 'd' => 2, 'c' => 3); //associative array

// rename $array['d'] as $array['b']
$array = replace_key_function($array, 'd', 'b');

var_export($array); // array('a' => 1, 'b' => 2, 'c' => 3); same order!

我没有看到这样做的功能。有办法做到这一点吗?

4

5 回答 5

28

http://ideone.com/nCZnY

$array = array('a' => 1, 'd' => 2, 'c' => 3); //associative array

// rename $array['d'] as $array['b']
$array = replace_key_function($array, 'd', 'b');

var_export($array); // array('a' => 1, 'b' => 2, 'c' => 3); same order!

function replace_key_function($array, $key1, $key2)
{
    $keys = array_keys($array);
    $index = array_search($key1, $keys);

    if ($index !== false) {
        $keys[$index] = $key2;
        $array = array_combine($keys, $array);
    }

    return $array;
}
于 2012-04-16T22:42:42.937 回答
4

接受的答案的逻辑存在缺陷。

如果你有这样的数组:

[
    'k1'=>'k1',
    'k2'=>'k2',
    'k3',
    'k4'=>'k4'
]

并将 'k4' 替换为 'something' 您将得到如下输出:

[
    'k1'=>'k1',
    'k2'=>'k2',
    'something' => 'k3',
    'k4'=>'k4'
]

这是解决问题的快速解决方案:

function replace_key_function($array, $key1, $key2)
{
    $keys = array_keys($array);
    //$index = array_search($key1, $keys);        
    $index = false;
    $i = 0;
    foreach($array as $k => $v){
        if($key1 === $k){
            $index = $i;
            break;
        }
        $i++;
    }

    if ($index !== false) {
        $keys[$index] = $key2;
        $array = array_combine($keys, $array);
    }

    return $array;
}

编辑:2014/12/03 如果将 array_search 的第三个参数(严格)设置为 true,则接受的答案确实有效。

于 2014-07-01T14:49:58.363 回答
3

除了使用循环之外,您总是可以用 扁平化为字符串json_encode(),执行字符串替换,然后json_decode()返回数组:

function replaceKey($array, $old, $new)
{  
    //flatten the array into a JSON string
    $str = json_encode($array);

    // do a simple string replace.
    // variables are wrapped in quotes to ensure only exact match replacements
    // colon after the closing quote will ensure only keys are targeted 
    $str = str_replace('"'.$old.'":','"'.$new.'":',$str);

    // restore JSON string to array
    return json_decode($str, TRUE);       
}

现在这不会检查与预先存在的键的冲突(很容易添加字符串比较检查),并且它可能不是大规模数组中单个替换的最佳解决方案..但是将数组展平为一个很好的部分用于替换的字符串是它有效地使替换递归,因为任何深度的匹配都在一次通过中被替换:

$arr = array(
    array(
         'name'     => 'Steve'
        ,'city'     => 'Los Angeles'
        ,'state'    => 'CA'
        ,'country'  => 'USA'
        ,'mother'   => array(
             'name'     => 'Jessica'
            ,'city'     => 'San Diego'
            ,'state'    => 'CA'
            ,'country'  => 'USA'
        )
    )
    ,array(
         'name'     => 'Sara'
        ,'city'     => 'Seattle'
        ,'state'    => 'WA'
        ,'country'  => 'USA'
        ,'father'   =>  array(
             'name'     => 'Eric'
            ,'city'     => 'Atlanta'
            ,'state'    => 'GA'
            ,'country'  => 'USA'
            ,'mother'   => array(
                 'name'     => 'Sharon'
                ,'city'     => 'Portland'
                ,'state'    => 'OR'
                ,'country'  => 'USA'
            )
        )
    )
);
$replaced = replaceKey($arr,'city','town');
print_r($replaced);

输出

Array
(
    [0] => Array
        (
            [name] => Steve
            [town] => Los Angeles
            [state] => CA
            [country] => USA
            [mother] => Array
                (
                    [name] => Jessica
                    [town] => San Diego
                    [state] => CA
                    [country] => USA
                )
        )

    [1] => Array
        (
            [name] => Sara
            [town] => Seattle
            [state] => WA
            [country] => USA
            [father] => Array
                (
                    [name] => Eric
                    [town] => Atlanta
                    [state] => GA
                    [country] => USA
                    [mother] => Array
                        (
                            [name] => Sharon
                            [town] => Portland
                            [state] => OR
                            [country] => USA
                        )
                )
        )
)
于 2015-09-16T08:30:18.240 回答
2

使用 PHP 5.3+ 的通用且简单的解决方案,使用array_walk

$array = array('a' => 1, 'd' => 2, 'c' => 3); //associative array

$array = replace_keys($array, array('d' => 'b'));
var_export($array); // array('a' => 1, 'b' => 2, 'c' => 3); same order!

function replace_keys(array $source, array $keyMapping) {
    $target = array();
    array_walk($source,
               function ($v, $k, $keyMapping) use (&$target) {
                    $mappedKey = isset($keyMapping[$k]) ? $keyMapping[$k] : $k;
                    $target[$mappedKey] = $v;
               },
               $keyMapping);
    return $target;
}
于 2015-01-27T22:27:18.563 回答
1

已经发布了一个很好的答案,但这是我的两便士:

$array = array('a'=>1, 'd'=>2, 'c'=>3);
// rename 'd' to 'b'
foreach($array as $k=>$v){
    if($k == 'd') { $k='b'; }
        $newarray[$k] = $v;
}
$array = $newarray;

作为对 mike-purcell 的回应,这对我上面的例子来说是一种更容易接受的方法吗?

changeKey($array, 'd', 'b');

function changeKey($array, $oldKey, $newKey)
{
    foreach($array as $k=>$v){
        if($k == $oldKey) { $k = $newKey; }
        $returnArray[$k] = $v;
    }
    return $returnArray;
}

我一直在寻求改进:)

于 2012-04-16T22:51:12.957 回答