更改PHP关联数组中的键

时间:2022-08-26 14:02:29

Say I have an array like this:

假设我有一个这样的数组:

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

How would I change the keys of the inside arrays? Say, I want to change "n" for "name" and "l" for "last_name". Taking into account that it can happen than an array doesn't have a particular key.

如何更改内部数组的键?比如说,我想把n换成“name”,把l换成“last_name”。考虑到它可能发生,而数组没有特定的键。

6 个解决方案

#1


9  

Using array_walk

使用array_walk

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

#2


13  

Something like this maybe:

这样的可能:

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

NOTE: this solution will change the order of the keys. To preserve the order, you'd have to recreate the array.

注意:这个解决方案将改变键的顺序。为了保存顺序,您必须重新创建数组。

#3


3  

You could have:

你可以:

  1. an array that maps the key exchange (to make the process parametrizable)
  2. 映射密钥交换的数组(使流程可参数化)
  3. a loop the processes the original array, accessing to every array item by reference
  4. 循环处理原始数组,通过引用访问每个数组项

E.g.:

例如:

$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]); 
        }
    }
}

In such a way, you can have other replacements simply adding a couple key/value to the $mapKeyArray variable.

通过这种方式,只需向$mapKeyArray变量添加一对键/值,就可以有其他替换。

This solution also works if some key is not available in the original array

如果原始数组中没有键,这个解决方案也可以工作

#4


1  

Just make a note of the old value, use unset to remove it from the array then add it with the new key and the old value pair.

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

#5


0  

You could use the array_flip function:

可以使用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);

#6


0  

Renaming the key AND keeping the ordering consistent (the later was important for the use case that the following code was written).

重命名键并保持顺序一致(对于编写了以下代码的用例来说,后面的操作很重要)。

<?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, $keys)] = $newKey;
            $data = array_combine($keys, $data);

            return true;
        }
    }

    return false;
}

And some unit tests (PHPUnit being used, but hopefully understandable as the purpose of the tests).

以及一些单元测试(使用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);
}

The AssertError assertion is available for PHPUnit from https://github.com/digitickets/phpunit-errorhandler

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

#1


9  

Using array_walk

使用array_walk

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

#2


13  

Something like this maybe:

这样的可能:

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

NOTE: this solution will change the order of the keys. To preserve the order, you'd have to recreate the array.

注意:这个解决方案将改变键的顺序。为了保存顺序,您必须重新创建数组。

#3


3  

You could have:

你可以:

  1. an array that maps the key exchange (to make the process parametrizable)
  2. 映射密钥交换的数组(使流程可参数化)
  3. a loop the processes the original array, accessing to every array item by reference
  4. 循环处理原始数组,通过引用访问每个数组项

E.g.:

例如:

$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]); 
        }
    }
}

In such a way, you can have other replacements simply adding a couple key/value to the $mapKeyArray variable.

通过这种方式,只需向$mapKeyArray变量添加一对键/值,就可以有其他替换。

This solution also works if some key is not available in the original array

如果原始数组中没有键,这个解决方案也可以工作

#4


1  

Just make a note of the old value, use unset to remove it from the array then add it with the new key and the old value pair.

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

#5


0  

You could use the array_flip function:

可以使用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);

#6


0  

Renaming the key AND keeping the ordering consistent (the later was important for the use case that the following code was written).

重命名键并保持顺序一致(对于编写了以下代码的用例来说,后面的操作很重要)。

<?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, $keys)] = $newKey;
            $data = array_combine($keys, $data);

            return true;
        }
    }

    return false;
}

And some unit tests (PHPUnit being used, but hopefully understandable as the purpose of the tests).

以及一些单元测试(使用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);
}

The AssertError assertion is available for PHPUnit from https://github.com/digitickets/phpunit-errorhandler

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