1

Given a multi-dimensional array A and a multi-dimensional array B. Replace or add the values in array A with the values in array B if the key exists in array B

$targetA = array(
        'delete'=>array( 
             'name'=>'a_delete_name',
             'url'=>'a_delete_url'),
        'edit'=>array(
             'name'=>'a_edit_name',
             'url'=>'a_edit_url',
         )
     )
$argumentB = array(
        'delete'=>false,
        'edit'=>array(
            'name'=>'b_edit_name'
         ),
         'forbid'=>array(
            'name'=>'b_forbid_name'
         ),
     )
$result = array(
        'delete'=>false,//replaced
        'edit'=>array(
            'name'=>'b_edit_name'
            'url'=>'a_edit_url'//not replaced!
         ),
         'forbid'=>array(
            'name'=>'b_forbid_name'
         ),
     )

Desired is the $result

5
  • 2
    What you have tried so far ? Commented May 2, 2019 at 6:14
  • But A:delete:name doesn't exist in B so way not add it? Can you please define the requirement better? And what have you tried? Commented May 2, 2019 at 6:14
  • use B to replace A@dWinder Commented May 2, 2019 at 6:16
  • i have tried by using the RecursiveArrayIterator to find the B`s every terminal path just like B: "delete,edit->name,forbid->name" then blocked,i have no idea Commented May 2, 2019 at 6:18
  • A['delete']=B['delete'];A['edit']['name']=B['edit']['name'];A['forbid']['name']=B['forbid']['name']; i tried in this way,but blocked Commented May 2, 2019 at 6:25

2 Answers 2

1

This works for your case:

/**
 * Modifies an array to recursively replace the values with another array
 * This function modifies the passed in array, and does not return anything
 * 
 * @param array $startArray Initial array, passed as reference and will be modified
 * @param array $replaceArray Array of values which will replace values in the $startArray
 */
function replaceRecursive(&$startArray, $replaceArray) {
    $keys = array_keys($replaceArray);
    foreach ($keys as $key) {
        if (isset($replaceArray[$key])) {
                // If this is another array recurse to replace inner values
            if (is_array($replaceArray[$key])) {

                // Create array key in startArray if it doesn't exist yet
                if (!is_array($startArray[$key])) {
                    $startArray[$key] = array();
                }

                replaceRecursive($startArray[$key], $replaceArray[$key]);
            }
            else {
                // Just replace the key
                $startArray[$key] = $replaceArray[$key];
            }
        }
    }
}

You can use the method like this:

$targetA = array(... some values ...);
$argumentB = array(... some values ...);
replaceRecursive($targetA, $argumentB);
var_dump($targetA);

Feel free to comment if you have any questions

Sign up to request clarification or add additional context in comments.

Comments

0
  /**
 * get path
 * @param $obj
 * @return array
 */
public function array_path($argumentB){
    $iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($argumentB), RecursiveIteratorIterator::SELF_FIRST);
    $paths = array();
    foreach ($iterator as $k => $v) {
        if (!$iterator->hasChildren()) {
            for ($p = array(), $i = 0, $z = $iterator->getDepth(); $i <= $z; $i++) {
                $p[] = $iterator->getSubIterator($i)->key();
            }
            $paths[] = $p;
        }
    }
    return $paths;
}


/**
 * get value of b
 * @param $path
 * @param $array
 * @return mixed
 */
public function get($path, $array) {
    $temp =& $array;
    foreach($path as $key) {
        $temp =& $temp[$key];
    }
    return $temp;
}

/**
 * set value to A
 * @param $path
 * @param array $array
 * @param null $value
 */
public function set($path, &$array=array(), $value=null) {
    //$path = explode('.', $path); //if needed
    $temp =& $array;

    foreach($path as $key) {
        $temp =& $temp[$key];
    }
    $temp = $value;
}

/**
 * main func
 * @param $argumentB
 * @return mixed
 */
public function resetting($argumentB){
    $paths=$this->array_path($argumentB);
    $targetA=include $this->config_file;
    foreach($paths as $v){
        $this->set($v,$config,$this->get($v,$argumentB));
    }
    return $targetA;
}

1 Comment

it is my solution! emmmmm! seems hard

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.