Z
Z
zap_temp2014-12-06 14:52:14
PHP
zap_temp, 2014-12-06 14:52:14

Who will provide assistance in writing a recursive algorithm for building an array tree in a loop?

Guys, please help. I want to build an array like this:

array(
    'id_1'  => array(
        'main'  =>  array('arg1', 'arg2'),
        'sub'  =>  array(),
    ),
    'id_2'  => array(
        'main'  =>  array('arg1', 'arg2'),
        'sub'  =>  array(
            'id_3'  => array(
                'main'  =>  array(),
                'sub'  =>  array(
                    'id_4'  => array(
                        'main'  =>  array(),
                        'sub'  =>  array(
                            'id_5'  => array(
                                'main'  =>  array('arg1', 'arg2'),
                                'sub'  =>  array(),
                        ),
                    ),
                    ),
                ),
            ),
        ),
    ),
)

I have a function that takes 4 arguments, here is its call:
$test->add('id_1','arg1','arg2');
$test->add('id_2','arg1','arg2');
$test->add('id_5','arg1','arg2', array('id_2','id_3','id_4'));

It means:
Запиши в array['id_1' ]['main'] = array('arg1', 'arg2')
Запиши в array['id_2' ]['main'] = array('arg1', 'arg2')
Запиши в array['id_2' ]['sub']['id_3' ]['sub']['id_4' ]['sub']['id_5']['main'] = array('arg1', 'arg2');

I implemented it like this:
protected static $elements = array();
public function add($id, $arg1, $arg2, array $parents = NULL){
        self::_add($id, $arg1, $arg2, $parents, self::$elements);
}
protected function _add(&$id, &$arg1, &$arg2, $parents, array &$storage,){
        if($parents === NULL){
            $storage[$id] = array(
                'main'  => array($arg1, $arg2),
                'sub'   => array(),
            );
        }else{
            $i = 0;
            $d = &$storage;
            foreach($parents as $child_of){
                if($i === count($parents) - 1){
                    $d['sub'][$id] = array($arg1, $arg2);
                }else{
                    if(!isset($d[$child_of]['sub'][$parents[$i+1]])){
                        $d[$child_of]['sub'][$parents[$i+1]] = array();
                    }
                    $d = &$d[$child_of]['sub'][$parents[$i+1]];
                }
                $i++;
            }
        }

    }

f53e14e363c240079b19794b416cb7e4.png
The result shows that somewhere I made a mistake, who will tell me where? Thank you!
P.S. Do not offer recursion, although I agree that the task would be solved easier on it. But alas - I ask for help only in the cycle. Thanks

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Alexey Yakhnenko, 2014-12-10
@ayahnenko

class StaticElementContainer {
  protected static $_elements = array();

  public static function getElements() {
    return self::$_elements;
  }

  public function addElement($id, $arg1, $arg2, $parents = array()) {
    if (empty($parents)) {
      self::$_elements[$id] = self::_prepareElement(array($arg1, $arg2));
    }
    else {
      $_elements = &self::$_elements;
      while ($parents) {
        $parent = array_shift($parents);
        if (!isset($_elements[$parent])) {
          $_elements[$parent] = self::_prepareElement();
        }

        $_elements = &$_elements[$parent]['sub'];
      }

      $_elements[$id] = self::_prepareElement(array($arg1, $arg2));
    }
  }

  protected static function _prepareElement($main = array(), $sub = array()) {
    return array(
      'main' => $main,
      'sub' => $sub,
    );
  }
}

$test = new StaticElementContainer();
$test->addElement('id_1','arg1','arg2');
$test->addElement('id_2','arg1','arg2');
$test->addElement('id_5','arg1','arg2', array('id_2','id_3','id_4'));

print_r(StaticElementContainer::getElements());

outputs:
Array
(
    [id_1] => Array
        (
            [main] => Array
                (
                    [0] => arg1
                    [1] => arg2
                )

            [sub] => Array
                (
                )

        )

    [id_2] => Array
        (
            [main] => Array
                (
                    [0] => arg1
                    [1] => arg2
                )

            [sub] => Array
                (
                    [id_3] => Array
                        (
                            [main] => Array
                                (
                                )

                            [sub] => Array
                                (
                                    [id_4] => Array
                                        (
                                            [main] => Array
                                                (
                                                )

                                            [sub] => Array
                                                (
                                                    [id_5] => Array
                                                        (
                                                            [main] => Array
                                                                (
                                                                    [0] => arg1
                                                                    [1] => arg2
                                                                )

                                                            [sub] => Array
                                                                (
                                                                )

                                                        )

                                                )

                                        )

                                )

                        )

                )

        )

)

avoid naming variables with the same letter
and making functions that take more than 2 parameters

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question