Přejmenování klíče pole

Školení, která pořádám

Asociativní pole svádí k tomu, aby se klíčům přiřadil nějaký význam. Kvůli tomu také může vzniknout požadavek na přejmenování klíče, PHP tuto možnost ale nenabízí – pouhé odstranění starého prvku a jeho přidání pod novým klíčem ho zařadí na konec pole a nepomůže ani funkce array_splice, která nezachová index nově vkládaného prvku.

Nejjednodušší způsob přejmenování klíče (který mě napadl) spočívá v získání samotných klíčů funkcí array_keys a jeho následným zkombinováním s původními hodnotami funkcí array_combine:

<?php
/** Přejmenování klíče v poli
* @param array asociativní pole
* @param string starý klíč
* @param string nový klíč
* @return array pole s přejmenovaným klíčem
* @copyright Jakub Vrána, https://php.vrana.cz/
*/
function array_key_rename($array, $old_key, $new_key) {
    $keys = array_keys($array);
    $keys[array_search($old_key, $keys)] = $new_key;
    return array_combine($keys, $array);
}
?>
Jakub Vrána, Řešení problému, 20.6.2008, diskuse: 10 (nové: 0)

Diskuse

Googy:

Myslím, že v tomhle případě jsi přestřelil. Přijde mi naprosto zbytečné používat zmíněné funkce, obzvlášť když pole obsahuje stovky nebo více záznamů ...
Navrhuji:
<?php
  $value
= $array[$old_key];
  unset($array[$old_key]);
  $array[$new_key] = $value;
?>

mixpulin:

Vaše řešení ale na rozdíl od toho uvedeného v článku nevrátí klíče (array_keys) v původním pořadí, což bylo, pokud jsem dobře pochopil článek, jedním z požadavků (viz narážka na array_splice).

Googy:

Mate pravdu, potrebu zachovat index jsem preskocil.

ikona Jakub Vrána OpenID:

Druhé možné řešení:
<?php
function array_key_rename($array, $old_key, $new_key) {
    $pos = array_search($old_key, array_keys($array));
    return array_slice($array, 0, $pos) + array($new_key => $array[$old_key]) + array_slice($array, $pos+1);
}
?>

Juraj H.:

Skúšal som na localhoste obe verzie a u pôvodnej bola doba spracovávanie kratšia v priemere asi o 12% (WinXP,triáda Vertrigo server).

Martin Sadový:

Tohle jsem jednu dobu potřeboval , přemýšlel jsem o tom ale funkce array_combine mě nenapadla :D , dikec Jakube

ikona Lukáš Francálek:

To bude ovšem správně fungovat POUZE u asociativních polí. Např.:
<?php
  $array
= array(0 => 1, 'stary' => 2);
  print_r($array);
  print_r(array_key_rename($array, 'stary', 'novy'));
?>
neprojde, protože:
<?php
 
echo ('jakykoli_retezec' == 0) ? 'rovnase' : 'nerovnase'; // rovnase
?>
Pokud chci kombinované pole, musím použít ve funkci array_search porovnání identity:
<?php
 
//$keys[array_search($old_key, $keys)] = $new_key;
  $keys[array_search($old_key, $keys, true)] = $new_key;
?>
což ovšem není taky žádná sláva :-(

ikona v6ak:

Jenže do jakykoli_retezec není možné dosadit jakýkoli řetězec, stačí rozumět konverzím:

>>> var_dump('123retezec'==0)
bool(false)

>>> var_dump('123retezec'==5)
bool(false)

>>> var_dump('123retezec'==123)
bool(true)

ikona Lukáš Francálek:

To je v pořádku, ale co to mění na tom co píšu? IMHO pořád platí "To bude ovšem správně fungovat POUZE u asociativních polí.", nebo kecám?

ikona v6ak:

To jo. Jen jsem komentoval tu rovnost řetězců.

Diskuse je zrušena z důvodu spamu.

avatar © 2005-2024 Jakub Vrána. Publikované texty můžete přetiskovat pouze se svolením autora. Ukázky kódu smíte používat s uvedením autora a URL tohoto webu bez dalších omezení Creative Commons. Můžeme si tykat. Skripty předpokládají nastavení: magic_quotes_gpc=Off, magic_quotes_runtime=Off, error_reporting=E_ALL & ~E_NOTICE a očekávají předchozí zavolání mysql_set_charset. Skripty by měly být funkční v PHP >= 4.3 a PHP >= 5.0.