【问题标题】:replace array keys with given respective keys用给定的相应键替换数组键
【发布时间】:2012-07-28 05:00:47
【问题描述】:

我有一个像下面这样的数组

$old = array(
       'a' => 'blah',
       'b' => 'key',
       'c' => 'amazing',
       'd' => array(
                0 => 'want to replace',
                1 => 'yes I want to'
              )
       );

我有另一个数组,其中包含要替换为键信息的键。

$keyReplaceInfoz = array('a' => 'newA', 'b' => 'newB', 'c' => 'newC', 'd' => 'newD');

我需要将数组$old 的所有键替换为数组$keyReplaceInfo 中的相应值。

输出应该是这样的

$old = array(
       'newA' => 'blah',
       'newB' => 'key',
       'newC' => 'amazing',
       'newD' => array(
                0 => 'want to replace',
                1 => 'yes I want to'
              )
       );

我必须手动完成,如下所示。我期待更好的选择。谁能提出更好的方法来实现这一点?

$new = array();
foreach ($old as $key => $value)
{
     $new[$keyReplaceInfoz[$key]] = $value;
}

我知道这可以更简单。

【问题讨论】:

    标签: php arrays multidimensional-array array-key


    【解决方案1】:
    array_combine(array_merge($old, $keyReplaceInfoz), $old)
    

    我认为这看起来比你提出的要容易。

    【讨论】:

    • array_combine 仅在键和值的顺序正确且每个键都有替换的情况下才有效。 (我自己认为这是一个解决方案)。
    • 其实上面唯一的问题是,如果没有替换每个键,它就行不通。由于 array_merge($old, $keyReplaceInfoz),排序不是问题。
    • 有几个问题,都与元素的数量有关。如果替换数组包含一个不在旧数组中的键,则会出现 PHP 警告(并且不会替换任何内容)。如果替换数组缺少旧数组中的键,则旧数组中的键将替换为它自己的 value
    • 你是对的。该行对 $keyReplaceInfoz 的结构做出了某些假设,提问者应指定是否所有键都可用。
    • 啊抱歉,这么多年后我正在阅读这些 cmets,感谢@Summoner 当时提供的出色帮助,是的,对于我的问题和案例,我为每一对都提供了新密钥旧钥匙。
    【解决方案2】:
    array_combine(
        ['newKey1', 'newKey2', 'newKey3'],
        array_values(['oldKey1' => 1, 'oldKey2' => 2, 'oldKey3' => 3])
    );
    

    只要您具有相同数量的值和相同的顺序,这应该可以解决问题。

    【讨论】:

      【解决方案3】:

      IMO 使用 array_combine、array_merge,甚至 array_intersect_key 都是大材小用。 原代码已经够好了,速度也很快。

      【讨论】:

        【解决方案4】:

        适配@shawn-k方案,这里使用array_walk的代码更简洁,它只会替换想要的键,当然你可以根据自己的方便修改

        array_walk($old, function($value,$key)use ($keyReplaceInfoz,&$old){
                $newkey = array_key_exists($key,$keyReplaceInfoz)?$keyReplaceInfoz[$key]:false;
                if($newkey!==false){$old[$newkey] = $value;unset($old[$key]);
                }
            });
        
            print_r($old);
        

        【讨论】:

          【解决方案5】:

          我刚刚在我自己的应用程序中解决了同样的问题,但是对于我的应用程序,$keyReplaceInfoz 就像白名单一样——如果找不到某个键,则从结果数组中删除整个元素,而匹配的白名单键被转换为新的价值观。

          我想您可以通过巧妙地使用 array_map (http://php.net/manual/en/function.array-map.php) 来应用相同的算法,从而减少总代码量,也许另一位慷慨的读者会这样做。

          function filterOldToAllowedNew($key_to_test){       
              return isset($keyReplaceInfoz[$key_to_test])?$keyReplaceInfoz[$key_to_test]:false;
          }   
          
          $newArray = array();
          
          foreach($old as $key => $value){
              $newkey = filterOldToAllowedNew($key);
              if($newkey){
                 $newArray[$newkey] = $value;
              }
          }
          
          print_r($newArray);
          

          【讨论】:

            【解决方案6】:

            这是我为同一主题实施的解决方案:

            /**
             * Replace keys of given array by values of $keys
             * $keys format is [$oldKey=>$newKey]
             *
             * With $filter==true, will remove elements with key not in $keys
             *
             * @param  array   $array
             * @param  array   $keys
             * @param  boolean $filter
             *
             * @return $array
             */
            function array_replace_keys(array $array,array $keys,$filter=false)
            {
                $newArray=[];
                foreach($array as $key=>$value)
                {
                    if(isset($keys[$key]))
                    {
                        $newArray[$keys[$key]]=$value;
                    }
                    elseif(!$filter)
                    {
                        $newArray[$key]=$value;
                    }
                }
            
                return $newArray;
            }
            

            【讨论】:

            • 这与问题本身显示的方法有何不同?
            • 因为此方法不需要为源数组中的每个键都有一个替换键。如果替换键数组上不存在源数组的任何键,则问题中显示的方法将给出一个错误
            • 你说得对,Juan,但我确信我将拥有所有可供更换的钥匙。问题是改进方法。您的方法仍然执行相同的循环!
            【解决方案7】:

            这个问题很老,但由于它首先出现在 Google 上,所以我想我会添加解决方案。

            // Subject
            $old = array('foo' => 1, 'baz' => 2, 'bar' => 3));
            
            // Translations    
            $tr  = array('foo'=>'FOO', 'bar'=>'BAR');
            
            // Get result
            $new = array_combine(preg_replace(array_map(function($s){return "/^$s$/";}, 
                       array_keys($tr)),$tr, array_keys($old)), $old);
            
            // Output
            print_r($new);
            

            结果:

            大批 ( [FOO] => 1 [巴兹] => 2 [酒吧] => 3 )

            【讨论】:

              【解决方案8】:

              这与数组顺序和数组计数无关。输出顺序和值将基于replaceKey。

              $replaceKey = array('a' => 'newA', 'b' => 'newB', 'c' => 'newC', 'd' => 'newD', 'e' => 'newE','f'=>'newF');
              
              $array = array(
                     'a' => 'blah',
                     'd' => array(
                              0 => 'want to replace',
                              1 => 'yes I want to'
                            ),
                     'noKey'=>'RESIDUAL',
                     'c' => 'amazing',
                     'b' => 'key',
                     );
              
              $filterKey = array_intersect_key($replaceKey,$array);
              $filterarray = array_intersect_key(array_merge($filterKey,$array),$filterKey);
              
              $replaced = array_combine($filterKey,$filterarray);
              
              //output
              var_export($replaced);
              //array ( 'newA' => 'blah', 'newB' => 'key', 'newC' => 'amazing', 'newD' => array ( 0 => 'want to replace', 1 => 'yes I want to' ) )
              

              【讨论】:

                【解决方案9】:

                如果您正在寻找用于多维数组的递归解决方案,请查看以下方法。它将替换所有请求的密钥,而保留所有其他密钥。

                /**
                 * Given an array and a set of `old => new` keys,
                 * will recursively replace all array keys that
                 * are old with their corresponding new value.
                 *
                 * @param mixed $array
                 * @param array $old_to_new_keys
                 *
                 * @return array
                 */
                function array_replace_keys($array, array $old_to_new_keys)
                {
                    if(!is_array($array)){
                        return $array;
                    }
                
                    $temp_array = [];
                    $ak = array_keys($old_to_new_keys);
                    $av = array_values($old_to_new_keys);
                
                    foreach($array as $key => $value){
                        if(array_search($key, $ak, true) !== false){
                            $key = $av[array_search($key, $ak)];
                        }
                
                        if(is_array($value)){
                            $value = array_replace_keys($value, $old_to_new_keys);
                        }
                
                        $temp_array[$key] = $value;
                    }
                
                    return $temp_array;
                }
                

                使用 OP 的示例数组:

                $old = array(
                       'a' => 'blah',
                       'b' => 'key',
                       'c' => 'amazing',
                       'd' => array(
                                0 => 'want to replace',
                                1 => 'yes I want to'
                              )
                       );
                $replace = ["a" => "AA", 1 => 11];
                
                var_export(array_replace_keys($old, $replace));
                

                给出以下输出:

                array (
                  'AA' => 'blah',
                  'b' => 'key',
                  'c' => 'amazing',
                  'd' => 
                  array (
                    0 => 'want to replace',
                    11 => 'yes I want to',
                  ),
                )
                

                DEMO

                灵感来自following snippet

                【讨论】:

                  【解决方案10】:

                  这使用@Summonerexample,但牢记@Leighhint

                  $start = microtime();
                  $array = [ "a" => 1, "b" => 2, "c" => 3 ];
                  
                  function array_replace_key($array, $oldKey, $newKey) {
                      $keys = array_keys($array);
                      $idx = array_search($oldKey, $keys);
                      array_splice($keys, $idx, 1, $newKey);
                      return array_combine($keys, array_values($array));
                  }
                  
                  print_r(array_replace_key($array, "b", "z"));
                  

                  【讨论】:

                    【解决方案11】:
                        <?php
                    $new = array(); 
                    
                    foreach ($old as $key => $value)
                    {
                         $new[$keyReplaceInfoz][$key] = $value;
                    
                    }
                    ?>
                    

                    【讨论】:

                    • 这不会产生 OP 要求的输出数组。请在发布前检查您的代码。
                    【解决方案12】:
                    <?php
                    $old = array(
                           'a' => 'blah',
                           'b' => 'key',
                           'c' => 'amazing',
                           'd' => array(
                                    0 => 'want to replace',
                                    1 => 'yes I want to'
                                  )
                           );
                    $keyReplaceInfoz = array('a' => 'newA', 'b' => 'newB', 'c' => 'newC', 'd' => 'newD');
                    
                    $new = array(); 
                    
                    foreach ($old as $key => $value)
                    {
                        $newvalue =  $keyReplaceInfoz[$key];
                       $new[$key] = $newvalue;
                    }
                    print_r($new);
                    
                    ?>
                    

                    【讨论】:

                    • 这会改变值,我不想改变值,我想改变键。
                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2018-05-22
                    • 2022-12-06
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2012-07-26
                    相关资源
                    最近更新 更多