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
                        )

                )

        )

)
6
  • This doesn't help with the construction of a class but may help you figure it out: stackoverflow.com/questions/27929875/… Commented Jul 5, 2018 at 18:52
  • I fear the concept sub_array_start and sub_array_end really does not fit with how arrays work Commented Jul 5, 2018 at 19:00
  • @RiggsFolly, there must be a way to do it! I'm not very good at PHP, so cannot think further :( Commented Jul 5, 2018 at 19:02
  • 1
    Here is a hint, you have to track the current index (or at least call end() ) and the nesting level of the array pointer. ie. you have to maintain the state of where you are in the array Commented Jul 5, 2018 at 19:22
  • 1
    that is the trick isnt it Commented Jul 5, 2018 at 19:26

3 Answers 3

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;)

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

Comments

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;
    }
}

3 Comments

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.
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.
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.
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;
    }
}

1 Comment

Interesting use of JSON. Nice.

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.