在PHP中更改关联数组中的键

19

假设我有这样一个数组:

array(2) {
  [0]=> array(2) {
    ["n"]=> string(4) "john"
    ["l"]=> string(3) "red"
  }
  [1]=> array(2) {
    ["n"]=> string(5) "nicel"
    ["l"]=> string(4) "blue"
  }
}

我该如何更改内部数组的键?比如说,我想把“n”改为“name”,把“l”改为“last_name”。需要考虑到有些数组可能没有特定的键。


3
看这个:https://dev59.com/RXVC5IYBdhLWcg3wnCaA - Buksy
10个回答

23

使用array_walk

array_walk($array, function (& $item) {
   $item['new_key'] = $item['old_key'];
   unset($item['old_key']);
});

2
那个$item是从哪里来的? - Alisha Lamichhane
@AlishaLamichhane $item 将保存 $array 的值。 - begginer

19

可能是这样的:

if (isset($array['n'])) {
    $array['name'] = $array['n'];
    unset($array['n']);
}

注意:此解决方案将更改键的顺序。要保留顺序,您必须重新创建数组。


我可以看到这个在foreach里面能够工作,但是一旦出了foreach,它似乎仍然是旧的值。我猜我需要添加"&"。 - Hommer Smith

4

你可以:

  1. 拥有一个映射密钥交换的数组(以使该过程具有参数化)
  2. 循环处理原始数组,并通过引用访问每个数组项

例如:

$array = array( array('n'=>'john','l'=>'red'), array('n'=>'nicel','l'=>'blue') );

$mapKeyArray = array('n'=>'name','l'=>'last_name');

foreach( $array as &$item )
{
    foreach( $mapKeyArray as $key => $replace )
    {
        if (key_exists($key,$item))
        {
            $item[$replace] = $item[$key];
            unset($item[$key]); 
        }
    }
}

以这种方式,您可以通过向$mapKeyArray变量添加几个键/值来轻松添加其他替换项。
如果原始数组中缺少某些键,则此解决方案也适用。

1
重命名键并保持排序一致(后者对于以下代码的使用情况很重要)。
<?php
/**
 * Rename a key and preserve the key ordering.
 *
 * An E_USER_WARNING is thrown if there is an problem.
 *
 * @param array &$data The data.
 * @param string $oldKey The old key.
 * @param string $newKey The new key.
 * @param bool $ignoreMissing Don't raise an error if the $oldKey does not exist.
 * @param bool $replaceExisting Don't raise an error if the $newKey already exists.
 *
 * @return bool True if the rename was successful or False if the old key cannot be found or the new key already exists.
 */
function renameKey(array &$data, $oldKey, $newKey, $ignoreMissing = false, $replaceExisting = false)
{
    if (!empty($data)) {
        if (!array_key_exists($oldKey, $data)) {
            if ($ignoreMissing) {
                return false;
            }

            return !trigger_error('Old key does not exist', E_USER_WARNING);
        } else {
            if (array_key_exists($newKey, $data)) {
                if ($replaceExisting) {
                    unset($data[$newKey]);
                } else {
                    return !trigger_error('New key already exists', E_USER_WARNING);
                }
            }

            $keys = array_keys($data);
            $keys[array_search($oldKey, array_map('strval', $keys))] = $newKey;
            $data = array_combine($keys, $data);

            return true;
        }
    }

    return false;
}

还有一些单元测试(使用PHPUnit,但希望测试目的易于理解)。

public function testRenameKey()
{
    $newData = $this->data;
    $this->assertTrue(Arrays::renameKey($newData, 200, 'TwoHundred'));
    $this->assertEquals(
        [
            100 => $this->one,
            'TwoHundred' => $this->two,
            300 => $this->three,
        ],
        $newData
    );
}

public function testRenameKeyWithEmptyData()
{
    $newData = [];
    $this->assertFalse(Arrays::renameKey($newData, 'junk1', 'junk2'));
}

public function testRenameKeyWithExistingNewKey()
{
    Arrays::renameKey($this->data, 200, 200);
    $this->assertError('New key already exists', E_USER_WARNING);
}

public function testRenameKeyWithMissingOldKey()
{
    Arrays::renameKey($this->data, 'Unknown', 'Unknown');
    $this->assertError('Old key does not exist', E_USER_WARNING);
}

public function testRenameKeyWithMixedNumericAndStringIndicies()
{
    $data = [
        'nice', // Index 0
        'car' => 'fast',
        'none', // Index 1
    ];
    $this->assertTrue(Arrays::renameKey($data, 'car', 2));
    $this->assertEquals(
        [
            0 => 'nice',
            2 => 'fast',
            1 => 'none',
        ],
        $data
    );
}

PHPUnit中的AssertError断言可以从https://github.com/digitickets/phpunit-errorhandler获取。


1
我会更改: $keys[array_search($oldKey, $keys)] = $newKey;为: $keys[array_search($oldKey, array_map('strval', $keys))] = $newKey;这是我遇到的问题:http://php.net/manual/en/function.array-search.php#122377另外,我能够使用您的函数w/ array_walk(递归)。谢谢! - EllisGL
1
谢谢@EllisGL。我已经根据您的评论更新了答案,并添加了一个新的单元测试来覆盖这个特定问题。 - Richard A Quadling

1

只需记下旧值,使用unset将其从数组中删除,然后添加新键和旧值对。


0
这里提供了一种解决方案,可以更改数组的键,并且还可以保持在数组中的原始位置。它适用于关联数组。在我的情况下,值是对象,但我已经简化了这个例子。
// Our array
$fields = array(
    'first_name' => 'Radley',
    'last_name' => 'Sustaire',
    'date' => '6/26/2019', // <== Want to rename the key from "date" to "date_db"
    'amazing' => 'yes',
);

// Get the field value
$date_field = $fields['date'];

// Get the key position in the array (numeric)
$key_position = array_search( 'date', array_keys($fields) );

// Remove the original value
unset($fields['date']);

// Add the new value back in, with the new key, at the old position
$fields = array_merge(
    array_slice( $fields, 0, $key_position, true ),
    array( 'date_db' => $date_field ), // Notice the new key ends with "_db"
    array_slice( $fields, $key_position, null, true )
);

/*
Input:
Array(
    [first_name] => Radley
    [last_name] => Sustaire
    [date] => 6/26/2019
    [amazing] => yes
)

Output:
Array(
    [first_name] => Radley
    [last_name] => Sustaire
    [date_db] => 6/26/2019
    [amazing] => yes
)
*/

0
你可以使用array_flip函数:
$original = array('n'=>'john','l'=>'red');
$flipped = array_flip($original);
foreach($flipped as $k => $v){
    $flipped[$k] = ($v === 'n' ? 'name' : ($v === 'l' ? 'last_name' : $v));
}
$correctedOriginal = array_flip($flipped);

1
只有在您没有重复值的情况下。 - Davin

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

0

我遇到了类似的问题 - 需要从键中删除额外的后缀,这里是解决方法:

$arr = [
    'first_name_blah' => 'John',
    'last_name_bloh' => 'Smith',
    'age_bloh' => 99,
    'sex_bloh' => 'm',
];

foreach ($arr as $k => $v) {
    $newKey = preg_replace('/(_blah|_bloh|_bleh)$/', '', $k);
    if ($newKey !== $k) {
        $arr[$newKey] = $v;
        unset($arr[$k]);
    }
}

/* Result:
Array
(
    [first_name] => John
    [last_name] => Smith
    [age] => 99
    [sex] => m
)
*/
    

-1

通过参考

foreach($arr as &$m)
{
  $m['first_name'] = $m['n'];
  $m['last_name'] = $m['l'];
  unset($m['l'], m['n']);
}

print_r($arr);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接