Cannot Assign Key => Value to Foreach Array - php

I have the following array of countries ($countryIso = array("US","BR","CL");) and my idea is to create a new array to display the following schema:
('US', 200)
I tried to create the following structure:
$countryIso = array("US","BR","CL");
foreach ($countryIso as $isocode) {
$productcalc[] = "'" . strtoupper($isocode) . "'" . ',' . number_format($this->product->calculate($product = $product, $countryIso = $isocode), 0, '.', ',');
}
Despite I can create a look alike format, I realized that the array is not well formed. When I checked the output displays the following:
Array ( [0] => 'US',200
being the key is [0] and not US.
Any idea of how can I create a key => value result with
Array ( [US] => 200
using the foreach structure in my code? I tried with variants like array_combine to combine countryIso array with productcalc array but with no success

You can keep your iso array and simply just combine the arrays:
<?php
$iso = ['US', 'BR', 'CL'];
$values = [200, 300, 400]; # obviously populate this with your actual values
$newArray = array_combine($iso, $values); # array_combine($keys, $values)
echo '<pre>'. print_r($newArray, 1) .'</pre>';
Edit: Further thoughts if Values are got via iso value
<?php
$iso = ['US', 'BR', 'CL'];
$newArray = [];
foreach ($iso as $val)
{
$newArray[$val] = getValueFromIso($val); # not a real function - just an example
}

Just define the array with the correct values.
$countryIso =[
"US" => 200,
"BR" => 300,
"CL" => 400,
];
If the values need to be calculated use:
$countryIso = array("US","BR","CL");
foreach ($countryIso as $isocode) {
$productcalc[strtoupper($isocode)] = number_format($this->product->calculate($product = $product, $countryIso = $isocode), 0, '.', ',');
}
Now $productcalc is the array you need.

Related

PHP how to push an associative ARRAY (not its values) to another array?

The problem is the following:
I'm iterating over some data containing reservations for workstations with a foreach loop.
Inside this loop, I'm creating an associative array which looks like this:
$test = [
"id" => $id,
"name" => $forename." ".$surname,
"startDate" => date("Y-m-d", strtotime($startDate)-86400),
"endDate" => date("Y-m-d", strtotime($endDate)),
"color" => $color,
];
This array then shall be inserted into a numeric array (could be associative as well, but numeric would be easier).
I've tried array_merge, but it seems that it tries to insert the keys and their values into the destination array. This poses a problem, since the keys are always the same during each iteration. Therefore, during each iteration, the old keys and values are overwritten. Furthermore, I definitely NEED these arrays to stay arrays anyway, it would make life a lot easier for me later on.
I tried array_push but this doesnt seem to work, I get a NULL response.
Then I tried array_merge_recursively, and here the data is at least preserved, but it is split into numerical arrays indexed by the former associative key, referencing the data inside with numerical keys. This isnt the desired result either.
So how can I make it that I get this result:
$numericalArray = [[associativeArray1], [associativeArray2], [associativeArray3]]; //and so on
For further insight into my approach and the problems it causes, here's the function containing the foreach loop. The commented code contains the approaches I've already tried without success:
function createCalendarMarkupWithoutActiveDauerreservierung($connection, $allReservierungenData){
$calendarData = [];
//$calendarData = ["1"];
foreach($allReservierungenData as $reservierungData){
$color = setColorForDaterange($reservierungData['status']);
$username = retrieveReservierungUser($connection, $reservierungData["benutzer"]);
//$calendarData .= finalizeMarkupWithoutActiveDauerreservierung($reservierungData["id"], $username["vorname"], $username["name"], $reservierungData["anfang"], $reservierungData["ende"], $color);
$calendarDataSegment = finalizeMarkupWithoutActiveDauerreservierung($reservierungData["id"], $username["vorname"], $username["name"], $reservierungData["anfang"], $reservierungData["ende"], $color);
//$calendarData = array_merge($calendarData, ["2"]);
//$calendarData = array_merge($calendarData, $calendarDataSegment);
//$calendarData = array_push($calendarData, $calendarDataSegment);
//$calendarData = $calendarData + $calendarDataSegment;//array_merge($calendarData, $calendarDataSegment);
$calendarData = array_merge_recursive($calendarData, $calendarDataSegment);
}
return $calendarData;
}
Just append each array to your result:
<?php
$one = [
'id' => 'one',
'num' => 1
];
$result[] = $one;
$two = [
'id' => 'two',
'num' => 2
];
$result[] = $two;
var_export($result);
Output:
array (
0 =>
array (
'id' => 'one',
'num' => 1,
),
1 =>
array (
'id' => 'two',
'num' => 2,
),
)
If I understand you correctly, wouldn't you want something like this?
<?php
// example code
function createCalendarMarkupWithoutActiveDauerreservierung($connection, $allReservierungenData){
$calendarData = [];
foreach($allReservierungenData as $reservierungData){
$calendarDataSegment = finalizeMarkupWithoutActiveDauerreservierung($reservierungData["id"], $username["vorname"], $username["name"], $reservierungData["anfang"], $reservierungData["ende"], $color);
$calendarData = $calendarData[$reservierungData["id"]] = $calendarDataSegment);
}
return $calendarData;
}

How to get an associative array from a string?

This is the initial string:-
NAME=Marco\nLOCATION=localhost\nSECRET=fjsdgfsjfdskffuv=\n
This is my solution although the "=" in the end of the string does not appear in the array
$env = file_get_contents(base_path() . '/.env');
// Split string on every " " and write into array
$env = preg_split('/\s+/', $env);
//create new array to push data in the foreach
$newArray = array();
foreach($env as $val){
// Split string on every "=" and write into array
$result = preg_split ('/=/', $val);
if($result[0] && $result[1])
{
$newArray[$result[0]] = $result[1];
}
}
print_r($newArray);
This is the result I get:
Array ( [Name] => Marco [LOCATION] => localhost [SECRET] => fjsdgfsjfdskffuv )
But I need :
Array ( [Name] => Marco [LOCATION] => localhost [SECRET] => fjsdgfsjfdskffuv= )
You can use the limit parameter of preg_split to make it only split the string once
http://php.net/manual/en/function.preg-split.php
you should change
$result = preg_split ('/=/', $val);
to
$result = preg_split ('/=/', $val, 2);
Hope this helps
$string = 'NAME=Marco\nLOCATION=localhost\nSECRET=fjsdgfsjfdskffuv=\n';
$strXlate = [ 'NAME=' => '"NAME":"' ,
'LOCATION=' => '","LOCATION":"',
'SECRET=' => '","SECRET":"' ,
'\n' => '' ];
$jsonified = '{'.strtr($string, $strXlate).'"}';
$array = json_decode($jsonified, true);
This is based on 1) translation using strtr(), preparing an array in json format and then using a json_decode which blows it up nicely into an array...
Same result, other approach...
You can also use parse_str to parse URL syntax-like strings to name-value pairs.
Based on your example:
$newArray = [];
$str = file_get_contents(base_path() . '/.env');
$env = explode("\n", $str);
array_walk(
$env,
function ($i) use (&$newArray) {
if (!$i) { return; }
$tmp = [];
parse_str($i, $tmp);
$newArray[] = $tmp;
}
);
var_dump($newArray);
Of course, you need to put some sanity check in the function since it can insert some strange stuff in the array like values with empty string keys, and whatnot.

A couple of issues with PHP arrays

Here is how my code is supposed to work. I pull data from a few remote JSON urls and decode them back into normal arrays. Then I loop through those arrays and create a single combined array. While looping I do an array_search inside the combined array to see if the value for username already exists and return the key. If a key is returned then I combine the data from that key with the loops data. If the search returns false then I add the loop data to the end of the array.
There are a couple issues I am having and they could be related but I am not sure.
First, in my code when my array_search is ran it breaks the code.
Second, if I var_dump the master array above the array_search if statement then the array is populated with the first round of the loop, however when I look at the structure of the array from the dump I see that the array starts out strange and I don't know why.
Here is the code
$master_user_array = array();
foreach($url_list AS $url) {
$json = file_get_contents($url."?key=".self::AUTH_KEY);
$data = json_decode($json, true);
$user_count = 0;
foreach($data['user'] AS $user) {echo highlight_string(var_export($master_user_array, true));
if(count($master_user_array) > 0) {
$key = array_search($user['username'], array_column($master_user_array, 'username'));
} else {
$key = false;
}
if(false !== $key) {
$master_user_array[$key]['username'] = $user['username'];
$master_user_array[$key]['email'] = $user['email'];
$master_user_array[$key]['total']['counttoday'] += $user['counttoday'];
$master_user_array[$key]['total']['countweek'] += $user['countweek'];
$master_user_array[$key]['total']['countmonth'] += $user['countmonth'];
$master_user_array[$key]['total']['countyear'] += $user['countyear'];
$master_user_array[$key]['total']['counttotal'] += $user['counttotal'];
$master_user_array[$key]['sites'][$data['siteurl']]['counttoday'] = $user['counttoday'];
$master_user_array[$key]['sites'][$data['siteurl']]['countweek'] = $user['countweek'];
$master_user_array[$key]['sites'][$data['siteurl']]['countmonth'] = $user['countmonth'];
$master_user_array[$key]['sites'][$data['siteurl']]['countyear'] = $user['countyear'];
$master_user_array[$key]['sites'][$data['siteurl']]['counttotal'] = $user['counttotal'];
} else {
$master_user_array[$user_count]['username'] = $user['username'];
$master_user_array[$user_count]['email'] = $user['email'];
$master_user_array[$user_count]['total']['counttoday'] = $user['counttoday'];
$master_user_array[$user_count]['total']['countweek'] = $user['countweek'];
$master_user_array[$user_count]['total']['countmonth'] = $user['countmonth'];
$master_user_array[$user_count]['total']['countyear'] = $user['countyear'];
$master_user_array[$user_count]['total']['counttotal'] = $user['counttotal'];
$master_user_array[$user_count]['sites'][$data['siteurl']]['counttoday'] = $user['counttoday'];
$master_user_array[$user_count]['sites'][$data['siteurl']]['countweek'] = $user['countweek'];
$master_user_array[$user_count]['sites'][$data['siteurl']]['countmonth'] = $user['countmonth'];
$master_user_array[$user_count]['sites'][$data['siteurl']]['countyear'] = $user['countyear'];
$master_user_array[$user_count]['sites'][$data['siteurl']]['counttotal'] = $user['counttotal'];
$user_count++;
}
}
}
And here is the output from the var_dump notice the array starts with array (
) 1. If I get rid of the array_search and the code doesn't break then this part of the array is added to the beginning of every round of the loop. Always with a 1.
array (
) 1 array (
'' =>
array (
'username' => 'somename',
'email' => 'someemail',
'total' =>
array (
'counttoday' => 0,
'countweek' => 0,
'countmonth' => 0,
'countyear' => 0,
'counttotal' => 3,
),
'sites' =>
array (
'' =>
array (
'counttoday' => 0,
'countweek' => 0,
'countmonth' => 0,
'countyear' => 0,
'counttotal' => '3',
),
),
),
)
Just so everyone knows I went a different way. Rather than trying to make things so complicated I was able to simplify the array and get rid of the array_search altogether.

Combine two array in php

I have two array in php and now I want to combine this two array as below.
$a1 = Array(
'ansid4' => 4,
'ansid5' => 5,
'ansid6' => 6
);
$a2 = Array(
'value' => 'demo',
'value2' => 'demo2'
);
Required Output:
$target = Array(
4 => 'demo',
5 => 'demo2',
6 => Null
);
Thanks in advance
$resultArray = array();
while ($key = array_pop($arrayOne)) {
$resultArray[$key] = array_pop($arrayTwo);
}
or you could do
$resultArray = array();
foreach ($arrayOne as $key) {
$resultArray[$key] = array_shift($arrayTwo);
}
Both solutions have the disadvantage that they consume one or both arrays.
If you need them still after the combination you could make copies of the Arrays and have those consumed.
Take a look at array_combine
you can send to this function array of keys and array of values and it return assoc array
please notice that the two arrays must have the same number of elements.
if you cant take care of that, try using array_pad before
$targetArray = array('a'=>'','b'=>'');
$sourceArray = array('a'=>array(1,2,3),'c'=>'c','d'=>'d');
$result = array_merge( $targetArray, $sourceArray);
$array_text = recurse_array($result);
echo $array_text;
function recurse_array($values){
$content = '';
if( is_array($values) ){
foreach($values as $key => $value){
if( is_array($value) ){
$content.="$key<br />".recurse_array($value);
}else{
$content.="$key = $value<br />";
}
}
}
return $content;
}
You have to have the same number of elements in both arrays so we start with counting of elements and add necessary NULL values by array_pad
if (count($a1) > count($a2))
{
$a2 = array_pad1($a2, count($a1), NULL);
}
elseif (count($a1) < count($a2))
{
$a1 = array_pad($a1, count($a2), NULL);
}
Then we use array_combine, which creates new array. From both arrays we use values by array_values. From first array we use values as keys and from second array we use values as values:-)
$target = array_combine(array_values($a1), array_values($a2))

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