views:

90

answers:

3

Hello.

I have a multidimensional array with strings as keys. I want to perform a function (to manipulate the strings) on those keys and then write to a new array (i.e. leave the original array unchanged).

Example:

$oldArr = array(
    "foo_old" => array("moo_old" => 1234, "woo_old" => 5678);
    "bar_old" => array("car_old" => 4321, "tar_old" => 8765);
);

Becomes:

$newArr = array(
    "foo_new" => array("moo_new" => 1234, "woo_new" => 5678);
    "bar_new" => array("car_new" => 4321, "tar_new" => 8765);
);

This is just an example, the actual array has more levels/dimensions. Oh and my function doesn't replace "_old" with "_new", again, just an example.

I hope I made some sense, thanks in advance!

A: 

Something like this:

function renameKeys( $arr ) 
{
    if( is_array( $arr ) && count( $arr ) ) {
            foreach ( $arr as $k => $v ) {
                $nk = str_replace( '_old', '_new', $k );
                if( is_array( $v ) ) {
                    $v = renameKeys( $v );
                }
                $arr[ $nk ] = $v;
                unset( $arr[$k] );
            }
    }
    return $arr;
}
$oldArr = array(
    "foo_old" => array("moo_old" => 1234, "woo_old" => 5678) ,
        "bar_old" => array("car_old" => 4321, "tar_old" => 8765)
        );

$nArr = renameKeys( $oldArr );
print_r( $nArr );
Radek Suski
Except the OP does not want to change the original array, so you will want to return rather than use a reference. The other option would be to assign the new before calling the function.
Joseph
-1 this will produce an array containing the old values too
Thariama
@Joseph: right :)
Radek Suski
you modified your function, but nothing at all gets changed now!
Thariama
@Thariama: better ?? ;)
Radek Suski
yes, it is better now, removed the -1
Thariama
@Thariama: thanks :)
Radek Suski
Function works, but not if `$nk` is going to be the same as `$k` (after applying a function to `$k`, e.g. `$nk = strtolower($k)`) - then it just skips the key and doesn't add it to `$arr`. Do you have a solution for that? Thanks.
A: 

Edit: I added a function for printing out the changed array. You may include the code on a website and it will show the result. New edited code:

// array initialisation
oldArr = array();
$subArr1 = array();
$subArr2 = array();

$subArr1["moo_old"]=1234;
$subArr1["woo_old"]=5678;
$subArr2["car_old"]=4321;
$subArr2["tar_old"]=8765;
$oldArr["foo_old"]=$subArr1;
$oldArr["bar_old"]=$subArr2;

$oldArr;  // make a copy of the array

// function which replaces recursivly the keys of the array 
function renameArrayKeys( $oldArr ) {

 $copyArr = $oldArr;

    if( is_array( $oldArr) && count( $oldArr ) ) {
        foreach ( $oldArr as $k => $v ) {

            unset($copyArr[$k]); // removes old entries
            $newKey = str_replace( '_old', '_new', $k );

            if( is_array( $v ) ) {
    $copyArr[ $newKey ] = renameArrayKeys( $v );
            }
            else {
             $copyArr[ $newKey ] = $v;
            }
        }
        return $copyArr;
    }
}

// prints out the keys and values of the changed array
function printout($arr ){
 foreach ($arr as $k => $val ) {
  echo $k."=>".$val." | ";
  if( is_array( $val ) ) {
             printout( $val );
  }
 }
}

// calls the above functions
$changedArr = renameArrayKeys($oldArr);
printout($changedArr);
Thariama
you might want to pick another function name due to http://de2.php.net/manual/en/function.rename.php
Gordon
This: "Except the OP does not want to change the original array, so you will want to return rather than use a reference."
copied the array
Thariama
you need to initialize $arr_orig - i ' ll add this to the code
Thariama
Still the same. Did you actually test this?
well, i did - will check again
Thariama
+1  A: 

Since you mentioned your actual array does look different from the example you gave, using the code below might not be feasible. But then again, maybe it can be applied to your real word data.

var_dump(
    unserialize(
        str_replace('_old', '_new', serialize($oldArr))));

The code serializes the array into a String and then replaces all occurences of _old with _new, regardless of them being keys or not (your example just had numbers). The resulting string is unserialized again into an array.

Gordon
+1 nicely done!
Thariama