Multidimensional array to single array, with full key and separator [duplicate] - php

There are plenty of tips and code examples out there of accessing PHP arrays with dot notation, but I would like to do somewhat the opposite. I would like to take a multidimensional array like this:
$myArray = array(
'key1' => 'value1',
'key2' => array(
'subkey' => 'subkeyval'
),
'key3' => 'value3',
'key4' => array(
'subkey4' => array(
'subsubkey4' => 'subsubkeyval4',
'subsubkey5' => 'subsubkeyval5',
),
'subkey5' => 'subkeyval5'
)
);
And turn it into this (likely through some recursive function):
$newArray = array(
'key1' => 'value1',
'key2.subkey' => 'subkeyval',
'key3' => 'value3',
'key4.subkey4.subsubkey4' => 'subsubkeyval4',
'key4.subkey5.subsubkey5' => 'subsubkeyval5',
'key4.subkey5' => 'subkeyval5'
);

teh codez
$ritit = new RecursiveIteratorIterator(new RecursiveArrayIterator($myArray));
$result = array();
foreach ($ritit as $leafValue) {
$keys = array();
foreach (range(0, $ritit->getDepth()) as $depth) {
$keys[] = $ritit->getSubIterator($depth)->key();
}
$result[ join('.', $keys) ] = $leafValue;
}
output
Array
(
[key1] => value1
[key2.subkey] => subkeyval
[key3] => value3
[key4.subkey4.subsubkey4] => subsubkeyval4
[key4.subkey4.subsubkey5] => subsubkeyval5
[key4.subkey5] => subkeyval5
)
demo: http://codepad.org/YiygqxTM
I need to go, but if you need an explanation of that tomorrow, ask me.

This will handle an arbitrary level of nesting:
<? //PHP 5.4+
$dotFlatten = static function(array $item, $context = '') use (&$dotFlatten){
$retval = [];
foreach($item as $key => $value){
if (\is_array($value) === true){
foreach($dotFlatten($value, "$context$key.") as $iKey => $iValue){
$retval[$iKey] = $iValue;
}
} else {
$retval["$context$key"] = $value;
}
}
return $retval;
};
var_dump(
$dotFlatten(
[
'key1' => 'value1',
'key2' => [
'subkey' => 'subkeyval',
],
'key3' => 'value3',
'key4' => [
'subkey4' => [
'subsubkey4' => 'subsubkeyval4',
'subsubkey5' => 'subsubkeyval5',
],
'subkey5' => 'subkeyval5',
],
]
)
);
?>

There is already the answer with RecursiveIteratorIterator. But here is a more optimal solution, that avoids using nested loops:
$iterator = new RecursiveIteratorIterator(
new RecursiveArrayIterator($arr),
RecursiveIteratorIterator::SELF_FIRST
);
$path = [];
$flatArray = [];
foreach ($iterator as $key => $value) {
$path[$iterator->getDepth()] = $key;
if (!is_array($value)) {
$flatArray[
implode('.', array_slice($path, 0, $iterator->getDepth() + 1))
] = $value;
}
}
There are several points need to be made here. Notice the use of RecursiveIteratorIterator::SELF_FIRST constant here. It is important as the default one is RecursiveIteratorIterator::LEAVES_ONLY which wouldn't let us access all keys. So with this constant set, we start from the top level of an array and go deeper. This approach lets us store the history of keys and prepare the key when we rich leaf using RecursiveIteratorIterator::getDepth method.
Here is a working demo.

This is my take on a recursive solution, which works for arrays of any depth:
function convertArray($arr, $narr = array(), $nkey = '') {
foreach ($arr as $key => $value) {
if (is_array($value)) {
$narr = array_merge($narr, convertArray($value, $narr, $nkey . $key . '.'));
} else {
$narr[$nkey . $key] = $value;
}
}
return $narr;
}
Which can be called as $newArray = convertArray($myArray).

This another approach similar to Blafrat above - but handles simply arrays as values.
function dot_flatten($input_arr, $return_arr = array(), $prev_key = '')
{
foreach ($input_arr as $key => $value)
{
$new_key = $prev_key . $key;
// check if it's associative array 99% good
if (is_array($value) && key($value) !==0 && key($value) !==null)
{
$return_arr = array_merge($return_arr, dot_flatten($value, $return_arr, $new_key . '.'));
}
else
{
$return_arr[$new_key] = $value;
}
}
return $return_arr;
}
(The only case this wouldn't catch is where you had a value that was associative but the first key was 0.)
Note that the RecursiveIteratorIterator can be slower than regular recursive function.
https://xenforo.com/community/threads/php-spl-why-is-recursiveiteratoriterator-100x-slower-than-recursive-search.57572/
In this case using the sample array given for 1000 iterations php5.6, this code is twice as fast (recursive=.032 vs interator=.062) - but the difference is probably insignificant for most cases. Mainly I prefer recursive because I find the logic of the Iterator needlessly complicated for a simple use case like this.

Related

flattens a multi-dimensional array into a single level array that uses "dot" notation to indicate depth [duplicate]

There are plenty of tips and code examples out there of accessing PHP arrays with dot notation, but I would like to do somewhat the opposite. I would like to take a multidimensional array like this:
$myArray = array(
'key1' => 'value1',
'key2' => array(
'subkey' => 'subkeyval'
),
'key3' => 'value3',
'key4' => array(
'subkey4' => array(
'subsubkey4' => 'subsubkeyval4',
'subsubkey5' => 'subsubkeyval5',
),
'subkey5' => 'subkeyval5'
)
);
And turn it into this (likely through some recursive function):
$newArray = array(
'key1' => 'value1',
'key2.subkey' => 'subkeyval',
'key3' => 'value3',
'key4.subkey4.subsubkey4' => 'subsubkeyval4',
'key4.subkey5.subsubkey5' => 'subsubkeyval5',
'key4.subkey5' => 'subkeyval5'
);
teh codez
$ritit = new RecursiveIteratorIterator(new RecursiveArrayIterator($myArray));
$result = array();
foreach ($ritit as $leafValue) {
$keys = array();
foreach (range(0, $ritit->getDepth()) as $depth) {
$keys[] = $ritit->getSubIterator($depth)->key();
}
$result[ join('.', $keys) ] = $leafValue;
}
output
Array
(
[key1] => value1
[key2.subkey] => subkeyval
[key3] => value3
[key4.subkey4.subsubkey4] => subsubkeyval4
[key4.subkey4.subsubkey5] => subsubkeyval5
[key4.subkey5] => subkeyval5
)
demo: http://codepad.org/YiygqxTM
I need to go, but if you need an explanation of that tomorrow, ask me.
This will handle an arbitrary level of nesting:
<? //PHP 5.4+
$dotFlatten = static function(array $item, $context = '') use (&$dotFlatten){
$retval = [];
foreach($item as $key => $value){
if (\is_array($value) === true){
foreach($dotFlatten($value, "$context$key.") as $iKey => $iValue){
$retval[$iKey] = $iValue;
}
} else {
$retval["$context$key"] = $value;
}
}
return $retval;
};
var_dump(
$dotFlatten(
[
'key1' => 'value1',
'key2' => [
'subkey' => 'subkeyval',
],
'key3' => 'value3',
'key4' => [
'subkey4' => [
'subsubkey4' => 'subsubkeyval4',
'subsubkey5' => 'subsubkeyval5',
],
'subkey5' => 'subkeyval5',
],
]
)
);
?>
There is already the answer with RecursiveIteratorIterator. But here is a more optimal solution, that avoids using nested loops:
$iterator = new RecursiveIteratorIterator(
new RecursiveArrayIterator($arr),
RecursiveIteratorIterator::SELF_FIRST
);
$path = [];
$flatArray = [];
foreach ($iterator as $key => $value) {
$path[$iterator->getDepth()] = $key;
if (!is_array($value)) {
$flatArray[
implode('.', array_slice($path, 0, $iterator->getDepth() + 1))
] = $value;
}
}
There are several points need to be made here. Notice the use of RecursiveIteratorIterator::SELF_FIRST constant here. It is important as the default one is RecursiveIteratorIterator::LEAVES_ONLY which wouldn't let us access all keys. So with this constant set, we start from the top level of an array and go deeper. This approach lets us store the history of keys and prepare the key when we rich leaf using RecursiveIteratorIterator::getDepth method.
Here is a working demo.
This is my take on a recursive solution, which works for arrays of any depth:
function convertArray($arr, $narr = array(), $nkey = '') {
foreach ($arr as $key => $value) {
if (is_array($value)) {
$narr = array_merge($narr, convertArray($value, $narr, $nkey . $key . '.'));
} else {
$narr[$nkey . $key] = $value;
}
}
return $narr;
}
Which can be called as $newArray = convertArray($myArray).
This another approach similar to Blafrat above - but handles simply arrays as values.
function dot_flatten($input_arr, $return_arr = array(), $prev_key = '')
{
foreach ($input_arr as $key => $value)
{
$new_key = $prev_key . $key;
// check if it's associative array 99% good
if (is_array($value) && key($value) !==0 && key($value) !==null)
{
$return_arr = array_merge($return_arr, dot_flatten($value, $return_arr, $new_key . '.'));
}
else
{
$return_arr[$new_key] = $value;
}
}
return $return_arr;
}
(The only case this wouldn't catch is where you had a value that was associative but the first key was 0.)
Note that the RecursiveIteratorIterator can be slower than regular recursive function.
https://xenforo.com/community/threads/php-spl-why-is-recursiveiteratoriterator-100x-slower-than-recursive-search.57572/
In this case using the sample array given for 1000 iterations php5.6, this code is twice as fast (recursive=.032 vs interator=.062) - but the difference is probably insignificant for most cases. Mainly I prefer recursive because I find the logic of the Iterator needlessly complicated for a simple use case like this.

php iterate associative array each time from the beginning [duplicate]

There are plenty of tips and code examples out there of accessing PHP arrays with dot notation, but I would like to do somewhat the opposite. I would like to take a multidimensional array like this:
$myArray = array(
'key1' => 'value1',
'key2' => array(
'subkey' => 'subkeyval'
),
'key3' => 'value3',
'key4' => array(
'subkey4' => array(
'subsubkey4' => 'subsubkeyval4',
'subsubkey5' => 'subsubkeyval5',
),
'subkey5' => 'subkeyval5'
)
);
And turn it into this (likely through some recursive function):
$newArray = array(
'key1' => 'value1',
'key2.subkey' => 'subkeyval',
'key3' => 'value3',
'key4.subkey4.subsubkey4' => 'subsubkeyval4',
'key4.subkey5.subsubkey5' => 'subsubkeyval5',
'key4.subkey5' => 'subkeyval5'
);
teh codez
$ritit = new RecursiveIteratorIterator(new RecursiveArrayIterator($myArray));
$result = array();
foreach ($ritit as $leafValue) {
$keys = array();
foreach (range(0, $ritit->getDepth()) as $depth) {
$keys[] = $ritit->getSubIterator($depth)->key();
}
$result[ join('.', $keys) ] = $leafValue;
}
output
Array
(
[key1] => value1
[key2.subkey] => subkeyval
[key3] => value3
[key4.subkey4.subsubkey4] => subsubkeyval4
[key4.subkey4.subsubkey5] => subsubkeyval5
[key4.subkey5] => subkeyval5
)
demo: http://codepad.org/YiygqxTM
I need to go, but if you need an explanation of that tomorrow, ask me.
This will handle an arbitrary level of nesting:
<? //PHP 5.4+
$dotFlatten = static function(array $item, $context = '') use (&$dotFlatten){
$retval = [];
foreach($item as $key => $value){
if (\is_array($value) === true){
foreach($dotFlatten($value, "$context$key.") as $iKey => $iValue){
$retval[$iKey] = $iValue;
}
} else {
$retval["$context$key"] = $value;
}
}
return $retval;
};
var_dump(
$dotFlatten(
[
'key1' => 'value1',
'key2' => [
'subkey' => 'subkeyval',
],
'key3' => 'value3',
'key4' => [
'subkey4' => [
'subsubkey4' => 'subsubkeyval4',
'subsubkey5' => 'subsubkeyval5',
],
'subkey5' => 'subkeyval5',
],
]
)
);
?>
There is already the answer with RecursiveIteratorIterator. But here is a more optimal solution, that avoids using nested loops:
$iterator = new RecursiveIteratorIterator(
new RecursiveArrayIterator($arr),
RecursiveIteratorIterator::SELF_FIRST
);
$path = [];
$flatArray = [];
foreach ($iterator as $key => $value) {
$path[$iterator->getDepth()] = $key;
if (!is_array($value)) {
$flatArray[
implode('.', array_slice($path, 0, $iterator->getDepth() + 1))
] = $value;
}
}
There are several points need to be made here. Notice the use of RecursiveIteratorIterator::SELF_FIRST constant here. It is important as the default one is RecursiveIteratorIterator::LEAVES_ONLY which wouldn't let us access all keys. So with this constant set, we start from the top level of an array and go deeper. This approach lets us store the history of keys and prepare the key when we rich leaf using RecursiveIteratorIterator::getDepth method.
Here is a working demo.
This is my take on a recursive solution, which works for arrays of any depth:
function convertArray($arr, $narr = array(), $nkey = '') {
foreach ($arr as $key => $value) {
if (is_array($value)) {
$narr = array_merge($narr, convertArray($value, $narr, $nkey . $key . '.'));
} else {
$narr[$nkey . $key] = $value;
}
}
return $narr;
}
Which can be called as $newArray = convertArray($myArray).
This another approach similar to Blafrat above - but handles simply arrays as values.
function dot_flatten($input_arr, $return_arr = array(), $prev_key = '')
{
foreach ($input_arr as $key => $value)
{
$new_key = $prev_key . $key;
// check if it's associative array 99% good
if (is_array($value) && key($value) !==0 && key($value) !==null)
{
$return_arr = array_merge($return_arr, dot_flatten($value, $return_arr, $new_key . '.'));
}
else
{
$return_arr[$new_key] = $value;
}
}
return $return_arr;
}
(The only case this wouldn't catch is where you had a value that was associative but the first key was 0.)
Note that the RecursiveIteratorIterator can be slower than regular recursive function.
https://xenforo.com/community/threads/php-spl-why-is-recursiveiteratoriterator-100x-slower-than-recursive-search.57572/
In this case using the sample array given for 1000 iterations php5.6, this code is twice as fast (recursive=.032 vs interator=.062) - but the difference is probably insignificant for most cases. Mainly I prefer recursive because I find the logic of the Iterator needlessly complicated for a simple use case like this.

Search in a multidimensional assoc array

I have an array, looking like this:
[lund] => Array
(
[69] => foo
)
[berlin] => Array
(
[138] => foox2
)
[tokyo] => Array
(
[180] => foox2
[109] => Big entrance
[73] => foo
)
The thing is that there were duplicate keys, so I re-arranged them so I can search more specifically, I thought.
Previously I could just
$key = array_search('foo', $array);
to get the key but now I don't know how.
Question: I need key for value foo, from tokyo. How do I do that?
You can get all keys and value of foo by using this:
foreach ($array as $key => $value) {
$newArr[$key] = array_search('foo', $value);
}
print_r(array_filter($newArr));
Result is:
Array
(
[lund] => 69
[tokyo] => 109
)
If you don't mind about the hard code than you can use this:
array_search('foo', $array['tokyo']);
It just a simple example, you can modify it as per your requirement.
Try this
$a = array(
"land"=> array("69"=>"foo"),
"land1"=> array("138"=>"foo1"),
"land2"=> array('180' => 'foox2',
'109' => 'Big entrance',
'73' => 'foo'),
);
//print_r($a);
$reply = search_in_array($a, "foo");
print_r($reply);
function search_in_array($a, $search)
{
$result = array();
foreach($a as $key1 => $array ) {
foreach($array as $k => $value) {
if($value == "$search") {
array_push($result,"{$key1}=>{$k}");
breck;
}
}
}
return $result;
}
This function will return the key or null if the search value is not found.
function search($searchKey, $searchValue, $searchArr)
{
foreach ($searchArr as $key => $value) {
if ($key == $searchKey && in_array($searchValue, $value)) {
$results = array_search($searchValue, $value);
}
}
return isset($results) ? $results : null;
}
// var_dump(search('tokyo', 'foo', $array));
Since Question: I need key for value foo, from tokyo. How do i do that?
$key = array_search('foo', $array['tokyo']);
As a function:
function getKey($keyword, $city, $array) {
return array_search($keyword, $array[$city]);
}
// PS. Might be a good idea to wrap this array in an object and make getKey an object method.
If you want to get all cities (for example to loop through them):
$cities = array_keys($array);
I created solution using array iterator. Have a look on below solution:
$array = array(
'lund' => array
(
'69' => 'foo'
),
'berlin' => array
(
'138' => 'foox2'
),
'tokyo' => array
(
'180' => 'foox2',
'109' => 'Big entrance',
'73' => 'foo'
)
);
$main_key = 'tokyo'; //key of array
$search_value = 'foo'; //value which need to be search
$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($array));
foreach ($iterator as $key => $value) {
$keys = array();
if ($value == $search_value) {
$keys[] = $key;
for ($i = $iterator->getDepth() - 1; $i >= 0; $i--) {
$keys[] = $iterator->getSubIterator($i)->key();
}
$key_paths = array_reverse($keys);
if(in_array($main_key, $key_paths) !== false) {
echo "'{$key}' have '{$value}' value which traverse path is: " . implode(' -> ', $key_paths) . '<br>';
}
}
}
you can change value of $main_key and $serch_value according to your parameter. hope this will help you.
<?php
$lund = [
'69' => 'foo'
];
$berlin = [
'138' => 'foox2'
];
$tokyo = [
'180' => 'foox2',
'109' => 'Big entrance',
'73' => 'foo'
];
$array = [
$lund,
$berlin,
$tokyo
];
echo $array[2]['180']; // outputs 'foox2' from $tokyo array
?>
If you want to get key by specific key and value then your code should be:
function search_array($array, $key, $value)
{
if(is_array($array[$key])) {
return array_search($value, $array[$key]);
}
}
echo search_array($arr, 'tokyo', 'foo');
try this:
<?php
error_reporting(E_ALL | E_STRICT);
ini_set('display_errors', 'On');
$array=array("lund" => array
(
69 => "foo"
),
"berlin" => array
(
138 => "foox2"
),
"tokyo" => array
(
180 => "foox2",
109 => "Big entrance",
73 => "foo"
));
function search($array, $arrkey1, $arrvalue2){
foreach($array as $arrkey=>$arrvalue){
if($arrkey == $arrkey1){
foreach($arrvalue as $arrkey=>$arrvalue){
if(preg_match("/$arrvalue/i",$arrvalue2))
return $arrkey;
}
}
}
}
$result=search($array, "tokyo", "foo"); //$array=array; tokyo="inside array to check"; foo="value" to check
echo $result;
You need to loop through array, since its 2 dimensional in this case. And then find corresponding value.
foreach($arr as $key1 => $key2 ) {
foreach($key2 as $k => $value) {
if($value == "foo") {
echo "{$k} => {$value}";
}
}
}
This example match key with $value, but you can do match with $k also, which in this case is $key2.

Invoking Multidimensional Associative Arrays in Templates

I'm building a small template system and i'm looking for a way to invoke multidimensional associative arrays using dots. For example:
$animals = array(
'four-legged' => array (
'cute' => 'no',
'ugly' => 'no',
'smart' => array('best' => 'dog','worst' => 'willy')
),
'123' => '456',
'abc' => 'def'
);
Then, in my template, if I wanted to show 'dog', I would put:
{a.four-legged.smart.best}
Well, given a string with four-legged.smart.worst:
function getElementFromPath(array $array, $path) {
$parts = explode('.', $path);
$tmp = $array;
foreach ($parts as $part) {
if (!isset($tmp[$part])) {
return ''; //Path is invalid
} else {
$tmp = $tmp[$part];
}
}
return $tmp; //If we reached this far, $tmp has the result of the path
}
So you can call:
$foo = getElementFromPath($array, 'four-legged.smart.worst');
echo $foo; // willy
And if you want to write elements, it's not much harder (you just need to use references, and a few checks to default the values if the path doesn't exist)...:
function setElementFromPath(array &$array, $path, $value) {
$parts = explode('.', $path);
$tmp =& $array;
foreach ($parts as $part) {
if (!isset($tmp[$part]) || !is_array($tmp[$part])) {
$tmp[$part] = array();
}
$tmp =& $tmp[$part];
}
$tmp = $value;
}
Edit: Since this is in a template system, it may be worth while "compiling" the array down to a single dimension once, rather than traversing it each time (for performance reasons)...
function compileWithDots(array $array) {
$newArray = array();
foreach ($array as $key => $value) {
if (is_array($value)) {
$tmpArray = compileWithDots($value);
foreach ($tmpArray as $tmpKey => $tmpValue) {
$newArray[$key . '.' . $tmpKey] = $tmpValue;
}
} else {
$newArray[$key] = $value;
}
}
return $newArray;
}
So that would convert:
$animals = array(
'four-legged' => array (
'cute' => 'no',
'ugly' => 'no',
'smart' => array(
'best' => 'dog',
'worst' => 'willy'
)
),
'123' => '456',
'abc' => 'def'
);
Into
array(
'four-legged.cute' => 'no',
'four-legged.ugly' => 'no',
'four-legged.smart.best' => 'dog',
'four-legged.smart.worst' => 'willy',
'123' => '456',
'abc' => 'def',
);
Then your lookup just becomes $value = isset($compiledArray[$path]) ? $compiledArray[$path] : ''; instead of $value = getElementFromPath($array, $path);
It trades pre-computing for inline speed (speed within the loop)...

PHP rename array keys in multidimensional array

In an array such as the one below, how could I rename "fee_id" to "id"?
Array
(
[0] => Array
(
[fee_id] => 15
[fee_amount] => 308.5
[year] => 2009
)
[1] => Array
(
[fee_id] => 14
[fee_amount] => 308.5
[year] => 2009
)
)
foreach ( $array as $k=>$v )
{
$array[$k] ['id'] = $array[$k] ['fee_id'];
unset($array[$k]['fee_id']);
}
This should work
You could use array_map() to do it.
$myarray = array_map(function($tag) {
return array(
'id' => $tag['fee_id'],
'fee_amount' => $tag['fee_amount'],
'year' => $tag['year']
); }, $myarray);
$arrayNum = count($theArray);
for( $i = 0 ; $i < $arrayNum ; $i++ )
{
$fee_id_value = $theArray[$i]['fee_id'];
unset($theArray[$i]['fee_id']);
$theArray[$i]['id'] = $fee_id_value;
}
This should work.
Copy the current 'fee_id' value to a new key named 'id' and unset the previous key?
foreach ($array as $arr)
{
$arr['id'] = $arr['fee_id'];
unset($arr['fee_id']);
}
There is no function builtin doing such thin afaik.
This is the working solution, i tested it.
foreach ($myArray as &$arr) {
$arr['id'] = $arr['fee_id'];
unset($arr['fee_id']);
}
The snippet below will rename an associative array key while preserving order (sometimes... we must). You can substitute the new key's $value if you need to wholly replace an item.
$old_key = "key_to_replace";
$new_key = "my_new_key";
$intermediate_array = array();
while (list($key, $value) = each($original_array)) {
if ($key == $old_key) {
$intermediate_array[$new_key] = $value;
}
else {
$intermediate_array[$key] = $value;
}
}
$original_array = $intermediate_array;
Converted 0->feild0, 1->field1,2->field2....
This is just one example in which i get comma separated value in string and convert it into multidimensional array and then using foreach loop i changed key value of array
<?php
$str = "abc,def,ghi,jkl,mno,pqr,stu
abc,def,ghi,jkl,mno,pqr,stu
abc,def,ghi,jkl,mno,pqr,stu
abc,def,ghi,jkl,mno,pqr,stu;
echo '<pre>';
$arr1 = explode("\n", $str); // this will create multidimensional array from upper string
//print_r($arr1);
foreach ($arr1 as $key => $value) {
$arr2[] = explode(",", $value);
foreach ($arr2 as $key1 => $value1) {
$i =0;
foreach ($value1 as $key2 => $value2) {
$key3 = 'field'.$i;
$i++;
$value1[$key3] = $value2;
unset($value1[$key2]);
}
}
$arr3[] = $value1;
}
print_r($arr3);
?>
I wrote a function to do it using objects or arrays (single or multidimensional) see at https://github.com/joaorito/php_RenameKeys.
Bellow is a simple example, you can use a json feature combine with replace to do it.
// Your original array (single or multi)
$original = array(
'DataHora' => date('YmdHis'),
'Produto' => 'Produto 1',
'Preco' => 10.00,
'Quant' => 2);
// Your map of key to change
$map = array(
'DataHora' => 'Date',
'Produto' => 'Product',
'Preco' => 'Price',
'Quant' => 'Amount');
$temp_array = json_encode($original);
foreach ($map AS $k=>$v) {
$temp_array = str_ireplace('"'.$k.'":','"'.$v.'":', $temp);
}
$new_array = json_decode($temp, $array);
Multidimentional array key can be changed dynamically by following function:
function change_key(array $arr, $keySetOrCallBack = [])
{
$newArr = [];
foreach ($arr as $k => $v) {
if (is_callable($keySetOrCallBack)) {
$key = call_user_func_array($keySetOrCallBack, [$k, $v]);
} else {
$key = $keySetOrCallBack[$k] ?? $k;
}
$newArr[$key] = is_array($v) ? array_change_key($v, $keySetOrCallBack) : $v;
}
return $newArr;
}
Sample Example:
$sampleArray = [
'hello' => 'world',
'nested' => ['hello' => 'John']
];
//Change by difined key set
$outputArray = change_key($sampleArray, ['hello' => 'hi']);
//Output Array: ['hi' => 'world', 'nested' => ['hi' => 'John']];
//Change by callback
$outputArray = change_key($sampleArray, function($key, $value) {
return ucwords(key);
});
//Output Array: ['Hello' => 'world', 'Nested' => ['Hello' => 'John']];
I have been trying to solve this issue for a couple hours using recursive functions, but finally I realized that we don't need recursion at all. Below is my approach.
$search = array('key1','key2','key3');
$replace = array('newkey1','newkey2','newkey3');
$resArray = str_replace($search,$replace,json_encode($array));
$res = json_decode($resArray);
On this way we can avoid loop and recursion.
Hope It helps.

Categories