我有一个关联数组,key => value
其中键是一个数值,但它不是一个连续的数值.密钥实际上是一个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´..."
KernelM的答案很好,但是为了避免Greg在评论中提出的问题(冲突的密钥),使用新的数组会更安全
$newarr[$newkey] = $oldarr[$oldkey]; $oldarr=$newarr; unset($newarr);
您可以使用第二个关联数组,将人类可读的名称映射到id.这也将提供多对一的关系.然后做这样的事情:
echo 'Widgets: ' . $data[$humanreadbleMapping['Widgets']];
如果您还希望新数组键的位置与旧数组键的位置相同,则可以执行以下操作:
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; }
如果你的数组是递归的,你可以使用这个函数:测试这个数据:
$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; }
$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 ]; */
我喜欢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' )
这是一个帮助函数来实现:
/** * 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.