Skip to content
Advertisement

Method to change specific value inside multidimensional array

Given a class with a multidimensional array as private property.

I’m trying to write a method setValue() which could change any value of this private array by passing:

  • some kind of path to a specific value (e.g. $path = [‘lorem’ => [‘ipsum’ => [‘dolor’ => [‘sit’ => null]]]];)
  • the new value

Class Tree {
    private $tree = array(
        'lorem' => array(
            'ipsum' => array(
                'dolor' => array(
                    'sit' => 'old value'
                )
            ),
            'amet' => array(
                'consetetur' => array(
                    'sadipscing' => 'another value'
                )
            )
        )
    );

    // setValue has to be a recursive function I guess
    public function setValue($path, $value) {
        // ???
    }

    public function getTree() {
        return $this->tree;
    }
}

Thanks to a comment of Gabriel on php.net I was able to find a working solution.

You can see my solution among the answers below.

What I actualy want to know: What are alternative approaches?

Advertisement

Answer

There are some recursive array built-in functions that may help you here:

<?php
class Tree
{
    private $tree = 
    [
        'foo' =>
            [
                'bar' => 'baz',
                'qux' => 'quux'
            ]
    ];

    public function replaceLeaf($key, $value) {
        array_walk_recursive(
            $this->tree, 
            function(&$item, $index) use ($key, $value) {
                if($key === $index)
                    $item = $value;
            }
        );
    }

    public function replace($value) {
        $this->tree = array_replace_recursive(
            $this->tree,
            $value
        );
    }

    public function getTree()
    {
        return $this->tree;
    }
}

$tree = new Tree;

$tree->replaceLeaf('bar', 'stool');
$tree->replace(
    ['foo' => ['qux' => 'quack']]
);
var_export($tree->getTree());

Output:

array (
    'foo' => 
    array (
      'bar' => 'stool',
      'qux' => 'quack',
    ),
  )

However looking at your original question targeting the array is likely an easier syntax, especially if you are only changing one attribute at a time. You’d have to change the visibility of the array accordingly:

$tree->tree['foo']['qux'] = 'whatever';
User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement