oach
oach

Reputation: 441

Dynamically find value in multi-dimensional array based on array of values and change it

I have a multi-dimensional array that needs to be "searchable" based on provided keys that may represent multiple levels w/in the array and change that found value.

// array that needs to be searched
$array = [
  'one' => [
    'two' => [
      'three' => 'four',
    ],
  ],
  'five' => [
    'six' => 'eight',
  ],
];

// array that represent the change
$change = [
  'five|six' => 'seven',
];

I need to find $array['five']['six'] dynamically and change that value to the provided. There may be multiple changes and they could be of varying depths. Note: the arrays I am really using are larger and deeper,

Last attempt:

foreach ($change as $k => $v) {
  $keyList = '';
  $keys = explode('|', $k);
  foreach ($keys as $key) {
    $keyList .= '[' . $key . ']';
  }
  $array[$keyList] = $v;
  // throws a notice: Notice: Undefined index (realize it is a string representation of keys.
  // Tried some other ways but nothing is clicking
}

Upvotes: 1

Views: 96

Answers (1)

Sammitch
Sammitch

Reputation: 32232

Any time you need to traverse a data structure of arbitrary depth you're likely going to need recursion. For this you need a function to get an arbitrary path in the data, and another to set it.

function get_path($arr, $path) {
    $cur = array_shift($path);
    if( empty($path) ) {
        return $arr[$cur];
    } else {
        return get_path($arr[$cur], $path);
    }
}

function set_path(&$arr, $path, $value) {
    $cur = array_shift($path);
    if( empty($path) ) {
        $arr[$cur] = $value;
    } else {
        set_path($arr[$cur], $path, $value);
    }
}

foreach ($change as $k => $v) {
  $keys = explode('|', $k);
  set_path($array, $keys, $v);
}

var_dump($array);

Output:

array(2) {
  ["one"]=>
  array(1) {
    ["two"]=>
    array(1) {
      ["three"]=>
      string(4) "four"
    }
  }
  ["five"]=>
  array(1) {
    ["six"]=>
    string(5) "seven"
  }
}

Upvotes: 1

Related Questions