在PHP中,你如何改变数组元素的键?
我有一个形式为key => value
的关联数组,其中key是一个数值,但它不是一个连续的数值。 密钥实际上是一个ID号码,值是一个计数。 这对大多数情况来说都没问题,但是我想要一个函数来获取数组的人类可读的名字,并且使用它作为键,而不用改变它的值。
我没有看到这样做的函数,但我假设我需要提供旧密钥和新密钥(我有),并转换数组。 有没有这样做的有效方式?
$arr[$newkey] = $arr[$oldkey]; unset($arr[$oldkey]);
你会这样做,并保持数组的排序是通过将数组键,将其放入一个单独的数组中,查找并替换该数组中的键,然后将其与值组合。
这是一个功能,只是这样做:
function change_key( $array, $old_key, $new_key ) { if( ! array_key_exists( $old_key, $array ) ) return $array; $keys = array_keys( $array ); $keys[ array_search( $old_key, $keys ) ] = $new_key; return array_combine( $keys, $array ); }
如果您的array
是从数据库查询中构建的,则可以直接从mysql
语句中更改该键:
代替
"select ´id´ from ´tablename´..."
使用类似于:
"select ´id´ **as NEWNAME** from ´tablename´..."
您可以使用第二个关联数组,将人类可读的名称映射到ID。 这也将提供多对一的关系。 然后做这样的事情:
echo 'Widgets: ' . $data[$humanreadbleMapping['Widgets']];
KernelM的答案很好,但为了避免Greg在评论(冲突键)中提出的问题,使用新的数组会更安全
$newarr[$newkey] = $oldarr[$oldkey]; $oldarr=$newarr; unset($newarr);
如果你还想要新的数组键的位置与旧的一样,你可以这样做:
function change_array_key( $array, $old_key, $new_key) { if(!is_array($array)){ print 'You must enter a array as a haystack!'; exit; } if(!array_key_exists($old_key, $array)){ return $array; } $key_pos = array_search($old_key, array_keys($array)); $arr_before = array_slice($array, 0, $key_pos); $arr_after = array_slice($array, $key_pos + 1); $arr_renamed = array($new_key => $array[$old_key]); return $arr_before + $arr_renamed + $arr_after; }
我喜欢KernelM的解决方案,但是我需要一些能够处理潜在的密钥冲突的地方(新密钥可能与现有密钥匹配)。 这是我想出来的:
function swapKeys( &$arr, $origKey, $newKey, &$pendingKeys ) { if( !isset( $arr[$newKey] ) ) { $arr[$newKey] = $arr[$origKey]; unset( $arr[$origKey] ); if( isset( $pendingKeys[$origKey] ) ) { // recursion to handle conflicting keys with conflicting keys swapKeys( $arr, $pendingKeys[$origKey], $origKey, $pendingKeys ); unset( $pendingKeys[$origKey] ); } } elseif( $newKey != $origKey ) { $pendingKeys[$newKey] = $origKey; } }
然后你可以像这样循环一个数组:
$myArray = array( '1970-01-01 00:00:01', '1970-01-01 00:01:00' ); $pendingKeys = array(); foreach( $myArray as $key => $myArrayValue ) { // NOTE: strtotime( '1970-01-01 00:00:01' ) = 1 (a conflicting key) $timestamp = strtotime( $myArrayValue ); swapKeys( $myArray, $key, $timestamp, $pendingKeys ); } // RESULT: $myArray == array( 1=>'1970-01-01 00:00:01', 60=>'1970-01-01 00:01:00' )
如果你的数组是递归的,你可以使用这个函数:测试这个数据:
$datos = array ( '0' => array ( 'no' => 1, 'id_maquina' => 1, 'id_transaccion' => 1276316093, 'ultimo_cambio' => 'asdfsaf', 'fecha_ultimo_mantenimiento' => 1275804000, 'mecanico_ultimo_mantenimiento' =>'asdfas', 'fecha_ultima_reparacion' => 1275804000, 'mecanico_ultima_reparacion' => 'sadfasf', 'fecha_siguiente_mantenimiento' => 1275804000, 'fecha_ultima_falla' => 0, 'total_fallas' => 0, ), '1' => array ( 'no' => 2, 'id_maquina' => 2, 'id_transaccion' => 1276494575, 'ultimo_cambio' => 'xx', 'fecha_ultimo_mantenimiento' => 1275372000, 'mecanico_ultimo_mantenimiento' => 'xx', 'fecha_ultima_reparacion' => 1275458400, 'mecanico_ultima_reparacion' => 'xx', 'fecha_siguiente_mantenimiento' => 1275372000, 'fecha_ultima_falla' => 0, 'total_fallas' => 0, ) );
这里是功能:
function changekeyname($array, $newkey, $oldkey) { foreach ($array as $key => $value) { if (is_array($value)) $array[$key] = changekeyname($value,$newkey,$oldkey); else { $array[$newkey] = $array[$oldkey]; } } unset($array[$oldkey]); return $array; }
这是一个帮助功能来实现这一点:
/** * Helper function to rename array keys. */ function _rename_arr_key($oldkey, $newkey, array &$arr) { if (array_key_exists($oldkey, $arr)) { $arr[$newkey] = $arr[$oldkey]; unset($arr[$oldkey]); return TRUE; } else { return FALSE; } }
漂亮基于@KernelM的答案 。
用法:
_rename_arr_key('oldkey', 'newkey', $my_array);
它将在成功重命名时返回true ,否则返回false 。
简单的东西:
这个函数将接受目标$ hash,$ replacements也是一个包含newkey => oldkey关联的哈希。
这个函数将保留原始的顺序 ,但是对于性能和内存非常大的(如10k以上的记录)数组可能会有问题。
function keyRename(array $hash, array $replacements) { $new=array(); foreach($hash as $k=>$v) { if($ok=array_search($k,$replacements)) $k=$ok; $new[$k]=$v; } return $new; }
这个替代函数也会这样做, 性能和内存使用性能要好得多 ,代价是失去原有的顺序(这不应该是一个问题,因为它是散列表)!
function keyRename(array $hash, array $replacements) { foreach($hash as $k=>$v) if($ok=array_search($k,$replacements)) { $hash[$ok]=$v; unset($hash[$k]); } return $hash; }
这段代码将有助于将旧密钥更改为新密码
$i = 0; $keys_array=array("0"=>"one","1"=>"two"); $keys = array_keys($keys_array); for($i=0;$i<count($keys);$i++) { $keys_array[$keys_array[$i]]=$keys_array[$i]; unset($keys_array[$i]); } print_r($keys_array);
显示像
$keys_array=array("one"=>"one","two"=>"two");
$array = [ 'old1' => 1 'old2' => 2 ]; $renameMap = [ 'old1' => 'new1', 'old2' => 'new2' ]; $array = array_combine(array_map(function($el) use ($renameMap) { return $renameMap[$el]; }, array_keys($array)), array_values($array)); /* $array = [ 'new1' => 1 'new2' => 2 ]; */
这适用于重命名第一个键:
$a = ['catine' => 'cat', 'canine' => 'dog']; $tmpa['feline'] = $a['catine']; unset($a['catine']); $a = $tmpa + $a;
然后,print_r($ a)呈现一个修复的有序数组:
Array ( [feline] => cat [canine] => dog )
这适用于重命名任意键:
$a = ['canine' => 'dog', 'catine' => 'cat', 'porcine' => 'pig'] $af = array_flip($a) $af['cat'] = 'feline'; $a = array_flip($af)
的print_r($ A)
Array ( [canine] => dog [feline] => cat [porcine] => pig )
一个广义函数:
function renameKey($oldkey, $newkey, $array) { $val = $array[$oldkey]; $tmp_A = array_flip($array); $tmp_A[$val] = $newkey; return array_flip($tmp_A); }
有一个替代方法来改变一个数组元素的关键时使用一个完整的数组 – 而不改变数组的顺序。 这只是将数组复制到一个新的数组。
例如,我正在处理一个混合的多维数组,其中包含索引键和关联键 – 我想用它们的值替换整数键,而不会破坏顺序。
我通过切换所有数值数组项的键/值来实现这个功能 – 在这里:['0'=>'foo']。 请注意,订单是完整的。
<?php $arr = [ 'foo', 'bar'=>'alfa', 'baz'=>['a'=>'hello', 'b'=>'world'], ]; foreach($arr as $k=>$v) { $kk = is_numeric($k) ? $v : $k; $vv = is_numeric($k) ? null : $v; $arr2[$kk] = $vv; } print_r($arr2);
输出:
Array ( [foo] => [bar] => alfa [baz] => Array ( [a] => hello [b] => world ) )
如果您想一次替换几个键(保持顺序):
/** * Rename keys of an array * @param array $array (asoc) * @param array $replacement_keys (indexed) * @return array */ function rename_keys($array, $replacement_keys) { return array_combine($replacement_keys, array_values($array)); }
用法:
$myarr = array("a" => 22, "b" => 144, "c" => 43); $newkeys = array("x","y","z"); print_r(rename_keys($myarr, $newkeys)); //must return: array("x" => 22, "y" => 144, "z" => 43);
嗯,我没有测试过,但我认为这个代码工作
function replace_array_key($data) { $mapping = [ 'old_key_1' => 'new_key_1', 'old_key_2' => 'new_key_2', ]; $data = json_encode($data); foreach ($mapping as $needed => $replace) { $data = str_replace('"'.$needed.'":', '"'.$replace.'":', $data); } return json_decode($data, true); }