1

I'm trying to create a class by which i should be able to create array having any depth of arrays/values. But i cannot get find the way to do it. Any suggestions/hints/helps would be great.

Here is the codes

    class CreateArray{
        public function __construct() {

        }

        private $array = [];
        public function add_value($value){
            $this->array[] = $value;
            return $this;
        }

        public function sub_array_start() {
            // What to do here?!
            return $this;
        }

        public function sub_array_end() {
            // What to do here?!
            return $this;
        }

        public function get() {
            return $this->array;
        }
    }

    $d_array = new CreateArray();
    $d_array = $d_array
                    ->add_value([1, 2, 3])
                    ->sub_array_start()
                        ->add_value([3, 2, 8])
                        ->add_value([4, 2, 5])

                        ->sub_array_start()
                            ->add_value([4, 2, 5])
                            ->add_value([3, 2, 8])
                        ->sub_array_end()

                        ->add_value([4, 2, 5])
                    ->sub_array_end()

                    ->add_value([1, 2, 3])
                    ->add_value([1, 2, 3])

                    ->sub_array_start()
                        ->add_value([3, 2, 8])
                        ->add_value([4, 2, 5])

                        ->sub_array_start()
                            ->sub_array_start()
                                ->add_value([3, 2, 8])
                                ->add_value([4, 2, 5])

                                ->sub_array_start()
                                    ->add_value([3, 2, 8])
                                    ->add_value([4, 2, 5])
                                ->sub_array_end()

                            ->sub_array_end()

                            ->add_value([3, 2, 8])
                            ->add_value([4, 2, 5])
                        ->sub_array_end()
                    ->sub_array_end();
                    ->get();
    print_r($d_array);

Above codes should create an array like this -

    Array
(
    [0] => Array
        (
            [0] => 1
            [1] => 2
            [2] => 3
        )

    [1] => Array
        (
            [0] => Array
                (
                    [0] => 3
                    [1] => 2
                    [2] => 8
                )

            [1] => Array
                (
                    [0] => 4
                    [1] => 2
                    [2] => 5
                )

            [2] => Array
                (
                    [0] => Array
                        (
                            [0] => 4
                            [1] => 2
                            [2] => 5
                        )

                    [1] => Array
                        (
                            [0] => 3
                            [1] => 2
                            [2] => 8
                        )

                )

            [3] => Array
                (
                    [0] => 4
                    [1] => 2
                    [2] => 5
                )

        )

    [2] => Array
        (
            [0] => 1
            [1] => 2
            [2] => 3
        )

    [3] => Array
        (
            [0] => 1
            [1] => 2
            [2] => 3
        )

    [4] => Array
        (
            [0] => Array
                (
                    [0] => 3
                    [1] => 2
                    [2] => 8
                )

            [1] => Array
                (
                    [0] => 4
                    [1] => 2
                    [2] => 5
                )

            [2] => Array
                (
                    [0] => Array
                        (
                            [0] => Array
                                (
                                    [0] => 3
                                    [1] => 2
                                    [2] => 8
                                )

                            [1] => Array
                                (
                                    [0] => 4
                                    [1] => 2
                                    [2] => 5
                                )

                            [2] => Array
                                (
                                    [0] => Array
                                        (
                                            [0] => 3
                                            [1] => 2
                                            [2] => 8
                                        )

                                    [1] => Array
                                        (
                                            [0] => 4
                                            [1] => 2
                                            [2] => 5
                                        )

                                )

                        )

                    [1] => Array
                        (
                            [0] => 3
                            [1] => 2
                            [2] => 8
                        )

                    [2] => Array
                        (
                            [0] => 4
                            [1] => 2
                            [2] => 5
                        )

                )

        )

)
Xahed Kamal
  • 2,203
  • 1
  • 20
  • 41

3 Answers3

2

I think the easiest (but certainly not an efficient) way is to keep a simple simple list of the current keys inside your array. Then you can traverse down and add your values/sub-arrays in the right place (if the =& is unfamiliar, check the PHP manual for references). In code:

class CreateArray{
    private $array = [];
    private $keys = [];
    public function __construct() {
    }

    public function add_value($value){
        $tmp =& $this->array;
        foreach ($this->keys as $key) {
            $tmp =& $tmp[$key];
        }
        $tmp[] = $value;
        return $this;
    }

    public function sub_array_start() {
        $tmp =& $this->array;
        foreach ($this->keys as $key) {
            $tmp =& $tmp[$key];
        }
        $tmp[] = [];
        end($tmp);
        $this->keys[] = key($tmp);
        reset($tmp);
        return $this;
    }

    public function sub_array_end() {
        array_pop($this->keys);
        return $this;
    }

    public function get() {
        return $this->array;
    }
}

Note: You have an extra ; after your last sub_array_end(), but otherwise the example code works (unless I overlooked something while quickly comparing the print_r's;)

jh1711
  • 2,288
  • 1
  • 12
  • 20
0

I was bored so I started this. My brain is tired now but maybe this will help you or someone else in the proper direction:

class CreateArray{

    private $array;
    private $previous;
    private $current;

    public function __construct(){
        $this->current =& $this->array;
    }

    public function add_value($value){
        $this->current[] = $value;
        return $this;
    }

    public function sub_array_start() {
        $this->previous =& $this->current;
        $this->current =& $this->array[];
        return $this;
    }

    public function sub_array_end() {
        $this->array =& $this->previous;
        $this->current =& $this->array;
        return $this;
    }

    public function get() {
        return $this->array;
    }
}
AbraCadaver
  • 78,200
  • 7
  • 66
  • 87
  • This will not work on two or more consecutive sub_array_end() calls. You need to store and restore all previous nodes. That was the reason I half-assed my answer. – jh1711 Jul 05 '18 at 22:12
  • Yes, this is not complete and I don't expect any upvotes. Maybe you have an idea using this approach? Should be able to store a reference to the deepest level somehow. – AbraCadaver Jul 05 '18 at 22:24
  • Imho your idea is spot on for a clean implementation. You just need to use sth. like a stack for previous nodes. After that, there's just a little busy work left. E.g. `$this->current =& $this->array[];` needs to be replaced by 'add a new empty array to current, and make current point to it'. I'm too lazy to do it, but maybe somebody else will; or I get really bored. – jh1711 Jul 05 '18 at 22:43
0

I found a way to do it. Though i'm not sure if its perfect or not. But here is my own solution -

class CreateArray{
    public function __construct() {

    }

    private $json_string = '';

    public function add_value($value){
        $value = json_encode($value, true);
        $this->json_string .= $value . ',';
        return $this;
    }

    public function sub_array_start() {
        $this->json_string .= '[';
        return $this;
    }

    public function sub_array_end() {
        $this->json_string = substr($this->json_string, 0, -1);
        $this->json_string .= '],';
        return $this;
    }

    public function get() {
        $value = '[' . $this->json_string . ']';
        $value = str_replace('],]', ']]', $value);
        $value = str_replace('},]', '}]', $value);
        $value = json_decode($value);
        return $value;
    }
}
Xahed Kamal
  • 2,203
  • 1
  • 20
  • 41