【问题标题】:Change key in associative array in PHP在 PHP 中更改关联数组中的键
【发布时间】:2012-10-25 08:46:13
【问题描述】:

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

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”。考虑到它可能会发生,而不是数组没有特定的键。

【问题讨论】:

标签: php arrays associative-array


【解决方案1】:

使用 array_walk

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

【讨论】:

  • $item 是从哪里来的?
  • @AlishaLamichhane $item 将保存 $array 值。
【解决方案2】:

可能是这样的:

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

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

【讨论】:

  • 我可以看到这在 foreach 内部工作,但一旦在外部,似乎这些值仍然是旧的。我想我需要添加“&”。
【解决方案3】:

你可以:

  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 变量。

如果原始数组中的某些键不可用,此解决方案也有效

【讨论】:

    【解决方案4】:

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

    【讨论】:

      【解决方案5】:

      重命名键并保持顺序一致(后者对于编写以下代码的用例很重要)。

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

      AssertError 断言可用于来自https://github.com/digitickets/phpunit-errorhandler 的 PHPUnit

      【讨论】:

      • 我会更改:$keys[array_search($oldKey, $keys)] = $newKey; 更改为:$keys[array_search($oldKey, array_map('strval', $keys))] = $newKey; 这是我遇到的问题:php.net/manual/en/function.array-search.php#122377 我还能够使用您的函数 w/array_walk(递归)。谢谢!
      • 谢谢@EllisGL。我已经用你的评论更新了答案,以及一个新的单元测试来涵盖这个特定的问题。
      【解决方案6】:

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

      【讨论】:

      • 仅当您没有重复值时。
      【解决方案7】:
      function arrayReplaceKey($array, $oldKey, $newKey) {
          $r = array();
          foreach ($array as $k => $v) {
              if ($k === $oldKey) $k = $newKey;
              $r[$k] = $v;
          }
          return $r;
      }
      

      【讨论】:

        【解决方案8】:

        这是一种更改数组的键保持数组中的原始位置的解决方案。它适用于关联数组。在我的例子中,值是对象,但我已经简化了这个例子。

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

        【讨论】:

          【解决方案9】:

          通过reference

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

          【讨论】:

            猜你喜欢
            • 2016-08-21
            • 2021-03-14
            • 1970-01-01
            • 2015-07-01
            • 2014-09-23
            • 2021-09-10
            • 2019-02-21
            • 2015-08-05
            • 1970-01-01
            相关资源
            最近更新 更多