Getting key from returned array - php

I'm working in WooCommerce, but my question is related to basic PHP foreach statements.
I have a function that returns a multidimensional array. The topmost dimension, the key string is what I need. If you've familiar, $order->get_items();.
The order_item_id is stored as the key like this:
'488' => Array( /* Array stuffs */ )
That 488 is what I need. It wouldn't be a problem if the function I'm working with's foreach statement was:
foreach ($items as $k => $v)
Where I could just use $k, but it's set up as:
foreach ($items as $item)
Is there a way to set the value of the key in the array and pass it along as a parameter?
UPDATE:
Here is the function as it works.
foreach($order_items as $item) {
$product = $order->get_product_from_item($item);
$gc_enabled = get_post_meta($product->id, 'ignite_gift_enabled', true);
if ( ! $gc_enabled)
continue;
$coupon_prefix = get_post_meta($product->id, '_coupon_prefix', true);
if ( ! $coupon_prefix)
$coupon_prefix = '';
for ($x = 1; $x <= $item['qty']; $x++) {
$new_coupon = $this->adjust_voucher( $coupon_prefix, $mode, $msg_details, $order_id, $order_item_id, $product->id );
}
}
$order_items is an array of items, the keys of which I need to pass along to other functions referenced, specificaly adjust_voucher.

Just change the foreach syntax to be foreach($items as $key => $item). This would give you access to $key while not impacting any existing code in the loop which relies on $item.

Here's a quick and dirty approach. Would be expensive if you have a large array -- but otherwise it would work.
$items = $order->get_items();
array_walk($items, function(&$v, $i) { $v['id'] = $i; });
This code adds another key to the array called id and assigns it the current key value.
Requires PHP 5.4 +
Example
$arr = array(
486 => array(
'name' => 'Bob',
),
500 => array(
'name' => 'Sam',
),
);
array_walk($arr, function(&$v, $i) { $v['id'] = $i; });
print_r($arr);
Example Result
Array (
[486] => Array (
[name] => Bob
[id] => 486
)
[500] => Array (
[name] => Sam
[id] => 500
)
)

You can set the values in your array (if needed up the call stack)
I tried that, but there are values that are retrieved with
$item['foo']. I tried setting it to $v['foo'], but it broke.
foreach( $items as $key => &$item ) {
$item['id'] = $key;
/* $item now looks like
* [ 'id' => ...,
* ... ]
*/
} unset( $item ); //Needed otherwise references can become complicated

Related

PHP, how do you change the key of an array element?

Hello guys, and Happy new year!
How can I add keys to this array
$my_array = array( [0] => 703683 [1] => 734972 [2] => 967385 )
So I would like to add a single key to all values example:
$copy_array = array( ['id'] => 703683 ['id'] => 734972 ['id'] => 967385 )
I tried this solution:
new_arr = [];
foreach ($my_array as $key => $value) {
// code..
$new_arr['id'] = $value ;
}
Output:
( [id] => 703683 )
You can't. An array key is identifying the element it represents. If you set 'id' to be a specific value, then you set it to be another specific value, then you override the former with the latter. Having separate values as ids is self-contradictory anyway, unless they identify different objects. If that's the case, then you can change your code to
new_arr = [];
foreach ($my_array as $key => $value) {
// code..
$new_arr[] = ['id' => $value] ;
}
or even
new_arr = [];
foreach ($my_array as $key => $value) {
// code..
$new_arr[$value] = ['id' => $value] ;
}
but the only use of such a change would be if they have other attributes, which are not included in the codes above, since your question does not provide any specific information about them if they exist at all. If everything is only an id, then you might as well leave it with numeric indexes.

how to get the key and value in the object in list of array

How to get the distinct keys ($key) and multiple different values ($myObjectValues) in list of objects?
My expected outcome is distinct keys displays as column in table and its different values display as multiple rows. The column ($key) should not be hardcore and I plan to display in blade view.
Ideal:
Current Code:
foreach($x as $key => $item) {
print_r($key); //this is list number
foreach($item as $key => $myObjectValues){
print_r($key); //this is my object key
print_r($myObjectValues); //this is my object values
}
}
This is the json array object ($x).
Array(
[0] => stdClass Object
(
[milk_temperature] => 10
[coffeebean_level] => 124.022
)
[1] => stdClass Object
(
[milk_temperature] => 1099
[soya_temperature] => 10
[coffeebean_level] => 99.022
)
[2] => stdClass Object
(
[milk_temperature] => 1099
[coffeebean_level] => 99.022
)
)
You can do it like this, it's not the best approach in the world but it works and you can use it as an example. First you create a list with the table header titles and then start by printing the header and then the values.
<?php
$x = [
(object) [
'milk_temperature' => 10,
'coffeebean_level' => 124.022
],
(object) [
'milk_temperature' => 1099,
'soya_temperature' => 10,
'coffeebean_level' => 99.022
],
(object) [
'milk_temperature' => 1099,
'coffeebean_level' => 99.022
]
];
// list all the keys
$keys = [];
foreach($x as $key => $item) {
$keys = array_merge($keys, array_keys((array) $item));
}
$keys = array_unique($keys);
// echo the header
foreach ($keys as $key) {
echo $key . ' ';
}
echo "\n";
// echo the values
foreach($x as $item) {
foreach ($keys as $key) {
echo $item->$key ?? '-'; // PHP 7+ solution
// echo isset($item->$key) ? $item->$key : '-'; // PHP 5.6+
echo ' ';
}
echo "\n";
}
You can first get the keys of the array with array_keys() and array_collapse():
$columns = array_keys(array_collapse($records));
Then you look through the $records using the same loop you already have. Let's demo it with this example:
$columns = array_keys(array_collapse($records));
foreach($records as $key => $item) {
//these are each record
foreach ($columns as $column) {
//each column where you build the header
// converts $item to an array
$item = (array)$item;
if (! array_key_exists($column, (array)$item)) {
// show '---'
echo '---';
continue;
}
//show $item[$item]
echo $item[$column];
}
}
The great advantage of doing so i.e getting the columns first (apart from converting the stdClass to an array) is that the columns array can be used any way you deem fit.
It would be more beneficial if you can have your data all as array then you can easily use the array functions available on it.

Create a hierarchical list of array elements

I have a an array of products. Each product contains its category and subcategories listed in a hierarchical order:
Array
(
[product_id_1] => Array
(
[0] => Men
[1] => Sunglasses
[2] => Luxury
[3] => Ray-ban
)
[product_id_2] => Array
(
[0] => Women
[1] => Lenses
[2] => Casual
[3] => Gucci
)
[product_id_3] => Array
(
[0] => Men
[1] => Sunglasses
[2] => Casual
[3] => Prada
)
[...]
)
I want to create an unordered hierarchical HTML menu like so:
-Men
--Sunglasses
---Luxury
----Ray-ban
---Casual
----Prada
-Women
--Lenses
---Casual
----Gucci
The function should strip out repetitive categories and subcategories. This script returns the array of products that I've posted at the top:
<?php
function displayNestedMenu( $posts, $taxonomies ) {
foreach ( $posts as $post ) {
foreach ( $taxonomies as $key => $taxonomy ) {
$push = wp_get_object_terms( $post->ID, $taxonomy );
if ( !empty( $push ) ) {
$list[$post->ID][] = $push[0]->name;
}
}
}
return $list;
}
print_r( displayNestedMenu( $posts, $taxonomies ) );
?>
I imagine the solution should invoke the function inside the function but after trying a couple of methods I haven't succeeded yet. Any suggestions are appreciated!
Here is a simple idea :
$array = array(
'product_id_1' => array(
'Men',
'Sunglasses',
'Luxury',
'Ray-ban'
),
'product_id_2' => array(
'Women',
'Lenses',
'Casual',
'Gucci',
),
'product_id_3' => array(
'Men',
'Sunglasses',
'Casual',
'Prada'
)
);
The idea is to recreate the keys depending on the parent category, after that we sort them using ksort():
function tree($array){
$newArray = array();
foreach ($array as $arr) {
foreach ($arr as $key => $row) {
if ($key > 0) {
$index = array();
for ($i = 0; $i <= $key; $i++)
$index[] = $arr[$i];
$index = implode('_', $index);
} else
$index = $row;
$newArray[$index] = $row;
}
}
ksort($newArray);
return $newArray;
}
Then display the HTML :
$products = tree($array);
$i = 0;
echo '<ul style="list-style-type:none">';
foreach ($products as $key => $row) {
if(strcmp($row, $key) == 0 && $i != 0)
echo '</ul><br><ul style="list-style-type:none">';
++$i;
$level = count(explode('_', $key));
$padding = 15 * (--$level);
echo
'<li style="padding-left:' . $padding . 'px">
<span style="border-left:1px dashed black;border-bottom:1px dashed black;"> ' . $row . '</span>
</li>';
}
echo '</ul>';
PHP has powerful array features: string-indexed arrays can help provide solutions to problems like this one.
For the array conversion step:
$hrchy=array();
foreach($products AS $product){//$products is as per your first array, at start…
hrchy_ins($hrchy,$product);
}
function hrchy_ins(array &$hierarchy,array $product){//$hierarchy should be passed by reference…
if(\count($product)>0){//Condition necessary to implement base case, avoiding infinite recursion
if(!isset($hierarchy[$product[0]])){$hierarchy[$product[0]]=array();}//Conditional execution ignores duplicates…
if(\count($product)>1){hrchy_ins($hierarchy[$product[0]],\array_slice($product,1));}//Condition may not be strictly necessary (see condition above!)
} }
We might now use a recursive approach for a further HTML-writing step (the recursion secret sauce = a simple recursive function including a branch-on-condition for the base-case):
function prod_list(array $hierarchy){
if(\count($hierarchy)===0){
return '';
}else{
$list='';
$list.='<ul>';
foreach($hierarchy AS $cat => $children){
$list.='<li>'.$cat;
$list.=prod_list($children);//Recursive step…
$list.='</li>';
}
$list.='<ul>';
return $list;
}
}
Finally, after defining the function, we invoke it:
echo(prod_list($hrchy));
Disclaimer: I have not tested this code.
You could transform the array in a static way, as the structure you describe always has four parts;
$hierarchy = array();
foreach($products as $product_id => $product) {
list($gender, $category, $type, $brand) = $product;
$hierarchy[$gender][$category][$type][$brand][] = $product_id;
}

How to search multiple keys from predefined array?

i have predefined array of categories like this in key => value pair
$all_categories = array (
1 => 'friends',
2 => 'family',
3 => 'personal',
4 => 'public'
);
and i have new small array like this which are only values.
$searched_categories = array('family','public');
Now how can i get the keys from $all_categories array having values as $searched_categories ?
i want output like this
$output_array = array(2,4);
i can get single key using array_search but is there a prebuilt function for this ? or i have to create a loop to array_search all the values i have ?
is this proper way of achieving this ?
$output_array = array ();
foreach ($searched_categories as $value){
$key = array_search($value, $all_categories );
$output_array = $key;
}
$all_categories = array (1 => 'friends', 2 => 'family', 3 => 'personal', 4 => 'public');
$searched_categories = array('family','public');
$output_array = array_keys(
array_intersect(
$all_categories,
$searched_categories
)
);
var_dump($output_array);
You could use a foreach loop and in_array.
foreach($all_categories as $key => $category){ //loop through your categories array
if(in_array($category, $searched_categories)){ //check if category is in searched_catgories
$output_array[] = $key; //if category is there, then save the key to your new array
}
}
print_r($output_array); will give you Array ( [0] => 2 [1] => 4 )
array_search is doing the job, but you erase your array all the time and add $key regardless of the fact it could be equal to false from array_search :
foreach ($searched_categories as $value){
$key = array_search($value, $all_categories );
if ($key !== false)
$output_array[] = $key;
}

Replace keys in an array based on another lookup/mapping array

I have an associative array in the form key => value where key is a numerical value, however it is not a sequential numerical value. The key is actually an ID number and the value is a count. This is fine for most instances, however I want a function that gets the human-readable name of the array and uses that for the key, without changing the value.
I didn't see a function that does this, but I'm assuming I need to provide the old key and new key (both of which I have) and transform the array. Is there an efficient way of doing this?
$arr[$newkey] = $arr[$oldkey];
unset($arr[$oldkey]);
The way you would do this and preserve the ordering of the array is by putting the array keys into a separate array, find and replace the key in that array and then combine it back with the values.
Here is a function that does just that:
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 );
}
if your array is built from a database query, you can change the key directly from the mysql statement:
instead of
"select ´id´ from ´tablename´..."
use something like:
"select ´id´ **as NEWNAME** from ´tablename´..."
The answer from KernelM is nice, but in order to avoid the issue raised by Greg in the comment (conflicting keys), using a new array would be safer
$newarr[$newkey] = $oldarr[$oldkey];
$oldarr=$newarr;
unset($newarr);
$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
];
*/
You could use a second associative array that maps human readable names to the id's. That would also provide a Many to 1 relationship. Then do something like this:
echo 'Widgets: ' . $data[$humanreadbleMapping['Widgets']];
If you want also the position of the new array key to be the same as the old one you can do this:
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;
}
Simple benchmark comparison of both solution.
Solution 1 Copy and remove (order lost, but way faster) https://stackoverflow.com/a/240676/1617857
<?php
$array = ['test' => 'value', ['etc...']];
$array['test2'] = $array['test'];
unset($array['test']);
Solution 2 Rename the key https://stackoverflow.com/a/21299719/1617857
<?php
$array = ['test' => 'value', ['etc...']];
$keys = array_keys( $array );
$keys[array_search('test', $keys, true)] = 'test2';
array_combine( $keys, $array );
Benchmark:
<?php
$array = ['test' => 'value', ['etc...']];
for ($i =0; $i < 100000000; $i++){
// Solution 1
}
for ($i =0; $i < 100000000; $i++){
// Solution 2
}
Results:
php solution1.php 6.33s user 0.02s system 99% cpu 6.356 total
php solution1.php 6.37s user 0.01s system 99% cpu 6.390 total
php solution2.php 12.14s user 0.01s system 99% cpu 12.164 total
php solution2.php 12.57s user 0.03s system 99% cpu 12.612 total
If your array is recursive you can use this function:
test this data:
$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,
)
);
here is the function:
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;
}
I like KernelM's solution, but I needed something that would handle potential key conflicts (where a new key may match an existing key). Here is what I came up with:
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;
}
}
You can then cycle through an array like this:
$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' )
Here is a helper function to achieve that:
/**
* 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;
}
}
pretty based on #KernelM answer.
Usage:
_rename_arr_key('oldkey', 'newkey', $my_array);
It will return true on successful rename, otherwise false.
this code will help to change the oldkey to new one
$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);
display like
$keys_array=array("one"=>"one","two"=>"two");
Easy stuff:
this function will accept the target $hash and $replacements is also a hash containing newkey=>oldkey associations.
This function will preserve original order, but could be problematic for very large (like above 10k records) arrays regarding performance & memory.
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;
}
this alternative function would do the same, with far better performance & memory usage, at the cost of losing original order (which should not be a problem since it is hashtable!)
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;
}
This page has been peppered with a wide interpretation of what is required because there is no minimal, verifiable example in the question body. Some answers are merely trying to solve the "title" without bothering to understand the question requirements.
The key is actually an ID number and the value is a count. This is
fine for most instances, however I want a function that gets the
human-readable name of the array and uses that for the key, without
changing the value.
PHP keys cannot be changed but they can be replaced -- this is why so many answers are advising the use of array_search() (a relatively poor performer) and unset().
Ultimately, you want to create a new array with names as keys relating to the original count. This is most efficiently done via a lookup array because searching for keys will always outperform searching for values.
Code: (Demo)
$idCounts = [
3 => 15,
7 => 12,
8 => 10,
9 => 4
];
$idNames = [
1 => 'Steve',
2 => 'Georgia',
3 => 'Elon',
4 => 'Fiona',
5 => 'Tim',
6 => 'Petra',
7 => 'Quentin',
8 => 'Raymond',
9 => 'Barb'
];
$result = [];
foreach ($idCounts as $id => $count) {
if (isset($idNames[$id])) {
$result[$idNames[$id]] = $count;
}
}
var_export($result);
Output:
array (
'Elon' => 15,
'Quentin' => 12,
'Raymond' => 10,
'Barb' => 4,
)
This technique maintains the original array order (in case the sorting matters), doesn't do any unnecessary iterating, and will be very swift because of isset().
If you want to replace several keys at once (preserving order):
/**
* 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));
}
Usage:
$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);
You can use this function based on array_walk:
function mapToIDs($array, $id_field_name = 'id')
{
$result = [];
array_walk($array,
function(&$value, $key) use (&$result, $id_field_name)
{
$result[$value[$id_field_name]] = $value;
}
);
return $result;
}
$arr = [0 => ['id' => 'one', 'fruit' => 'apple'], 1 => ['id' => 'two', 'fruit' => 'banana']];
print_r($arr);
print_r(mapToIDs($arr));
It gives:
Array(
[0] => Array(
[id] => one
[fruit] => apple
)
[1] => Array(
[id] => two
[fruit] => banana
)
)
Array(
[one] => Array(
[id] => one
[fruit] => apple
)
[two] => Array(
[id] => two
[fruit] => banana
)
)
This basic function handles swapping array keys and keeping the array in the original order...
public function keySwap(array $resource, array $keys)
{
$newResource = [];
foreach($resource as $k => $r){
if(array_key_exists($k,$keys)){
$newResource[$keys[$k]] = $r;
}else{
$newResource[$k] = $r;
}
}
return $newResource;
}
You could then loop through and swap all 'a' keys with 'z' for example...
$inputs = [
0 => ['a'=>'1','b'=>'2'],
1 => ['a'=>'3','b'=>'4']
]
$keySwap = ['a'=>'z'];
foreach($inputs as $k=>$i){
$inputs[$k] = $this->keySwap($i,$keySwap);
}
This function will rename an array key, keeping its position, by combining with index searching.
function renameArrKey($arr, $oldKey, $newKey){
if(!isset($arr[$oldKey])) return $arr; // Failsafe
$keys = array_keys($arr);
$keys[array_search($oldKey, $keys)] = $newKey;
$newArr = array_combine($keys, $arr);
return $newArr;
}
Usage:
$arr = renameArrKey($arr, 'old_key', 'new_key');
this works for renaming the first key:
$a = ['catine' => 'cat', 'canine' => 'dog'];
$tmpa['feline'] = $a['catine'];
unset($a['catine']);
$a = $tmpa + $a;
then, print_r($a) renders a repaired in-order array:
Array
(
[feline] => cat
[canine] => dog
)
this works for renaming an arbitrary key:
$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
)
a generalized function:
function renameKey($oldkey, $newkey, $array) {
$val = $array[$oldkey];
$tmp_A = array_flip($array);
$tmp_A[$val] = $newkey;
return array_flip($tmp_A);
}
There is an alternative way to change the key of an array element when working with a full array - without changing the order of the array.
It's simply to copy the array into a new array.
For instance, I was working with a mixed, multi-dimensional array that contained indexed and associative keys - and I wanted to replace the integer keys with their values, without breaking the order.
I did so by switching key/value for all numeric array entries - here: ['0'=>'foo']. Note that the order is intact.
<?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);
Output:
Array (
[foo] =>
[bar] => alfa
[baz] => Array (
[a] => hello
[b] => world
)
)
best way is using reference, and not using unset (which make another step to clean memory)
$tab = ['two' => [] ];
solution:
$tab['newname'] = & $tab['two'];
you have one original and one reference with new name.
or if you don't want have two names in one value is good make another tab and foreach on reference
foreach($tab as $key=> & $value) {
if($key=='two') {
$newtab["newname"] = & $tab[$key];
} else {
$newtab[$key] = & $tab[$key];
}
}
Iterration is better on keys than clone all array, and cleaning old array if you have long data like 100 rows +++ etc..
One which preservers ordering that's simple to understand:
function rename_array_key(array $array, $old_key, $new_key) {
if (!array_key_exists($old_key, $array)) {
return $array;
}
$new_array = [];
foreach ($array as $key => $value) {
$new_key = $old_key === $key
? $new_key
: $key;
$new_array[$new_key] = $value;
}
return $new_array;
}
Here is an experiment (test)
Initial array (keys like 0,1,2)
$some_array[] = '6110';//
$some_array[] = '6111';//
$some_array[] = '6210';//
I must change key names to for example human_readable15, human_readable16, human_readable17
Something similar as already posted. During each loop i set necessary key name and remove corresponding key from the initial array.
For example, i inserted into mysql $some_array got lastInsertId and i need to send key-value pair back to jquery.
$first_id_of_inserted = 7;//lastInsertId
$last_loop_for_some_array = count($some_array);
for ($current_loop = 0; $current_loop < $last_loop_for_some_array ; $current_loop++) {
$some_array['human_readable'.($first_id_of_inserted + $current_loop)] = $some_array[$current_loop];//add new key for intial array
unset( $some_array[$current_loop] );//remove already renamed key from array
}
And here is the new array with renamed keys
echo '<pre>', print_r($some_array, true), '</pre>$some_array in '. basename(__FILE__, '.php'). '.php <br/>';
If instead of human_readable15, human_readable16, human_readable17 need something other. Then could create something like this
$arr_with_key_names[] = 'human_readable';
$arr_with_key_names[] = 'something_another';
$arr_with_key_names[] = 'and_something_else';
for ($current_loop = 0; $current_loop < $last_loop_for_some_array ; $current_loop++) {
$some_array[$arr_with_key_names[$current_loop]] = $some_array[$current_loop];//add new key for intial array
unset( $some_array[$current_loop] );//remove already renamed key from array
}
Hmm, I'm not test before, but I think this code working
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);
}
You can write simple function that applies the callback to the keys of the given array. Similar to array_map
<?php
function array_map_keys(callable $callback, array $array) {
return array_merge([], ...array_map(
function ($key, $value) use ($callback) { return [$callback($key) => $value]; },
array_keys($array),
$array
));
}
$array = ['a' => 1, 'b' => 'test', 'c' => ['x' => 1, 'y' => 2]];
$newArray = array_map_keys(function($key) { return 'new' . ucfirst($key); }, $array);
echo json_encode($array); // {"a":1,"b":"test","c":{"x":1,"y":2}}
echo json_encode($newArray); // {"newA":1,"newB":"test","newC":{"x":1,"y":2}}
Here is a gist https://gist.github.com/vardius/650367e15abfb58bcd72ca47eff096ca#file-array_map_keys-php.

Categories