简体   繁体   English

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

[英]Change key in associative array in PHP

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".比如说,我想将“n”更改为“name”,将“l”更改为“last_name”。 Taking into account that it can happen than an array doesn't have a particular key.考虑到它可能会发生,而不是数组没有特定的键。

Using array_walk使用 array_walk

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

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.要保留顺序,您必须重新创建数组。

You could have:你可以有:

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

Eg:例如:

$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如果原始数组中的某些键不可用,此解决方案也适用

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将其从数组中删除,然后使用新键和旧值对添加它。

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, array_map('strval', $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);
}

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

The AssertError assertion is available for PHPUnit from https://github.com/digitickets/phpunit-errorhandler AssertError 断言可用于来自https://github.com/digitickets/phpunit-errorhandler的 PHPUnit

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);
function arrayReplaceKey($array, $oldKey, $newKey) {
    $r = array();
    foreach ($array as $k => $v) {
        if ($k === $oldKey) $k = $newKey;
        $r[$k] = $v;
    }
    return $r;
}

Here is a solution to change the key of an array and also keep the original position within the array .这是更改数组键保持数组中原始位置的解决方案。 It is intended for associative arrays.它适用于关联数组。 In my case the values were objects but I've simplified this example.在我的例子中,值是对象,但我简化了这个例子。

// 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
)
*/

Passed by reference通过引用传递

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

print_r($arr);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM