0

I need help modifying arrays to reach a desired structure. I am sorry the example structure maybe big, but i wanted to show the structure better.

I have a target Array like below that I need to generate

[bf_1040242] => Array
                (
                    [326] => Just some Information.  Additional Text
                    [17565] => Array
                        (
                            [0] => 2
                            [1] => 1
                            [2] => 3
                        )

                    [other] => Array
                        (
                            [17565] => Testing
                            [28623] => 
                            [42284] => Something Else
                        )

                    [597] => 1
                    [327] => This is some text
                    [328] => asdasd
                    [11880] => wwwww
                    [329] => xxxxx
                    [28622] => 2
                    [42283] => 1
                    [42284] => Array
                        (
                            [0] => 2
                            [1] => 3
                            [2] => 4
                        )

The data for me to generate this comes in a different format where the structure of these values are in string.

Array
(
    [0] => Array
        (
            [name] => bf_1040242[326]
            [value] => Just some Information. Additional Text
        )

    [1] => Array
        (
            [name] => bf_1040242[17565][]
            [value] => 2
        )

    [2] => Array
        (
            [name] => bf_1040242[17565][]
            [value] => 1
        )

    [3] => Array
        (
            [name] => bf_1040242[17565][]
            [value] => 3
        )

    [4] => Array
        (
            [name] => bf_1040242[other][17565]
            [value] => Testing
        )

    [5] => Array
        (
            [name] => bf_1040242[597]
            [value] => 1
        )

    [6] => Array
        (
            [name] => bf_1040242[327]
            [value] => This is some text
        )

    [7] => Array
        (
            [name] => bf_1040242[328]
            [value] => asdasd
        )

    [8] => Array
        (
            [name] => bf_1040242[11880]
            [value] => wwwww
        )

    [9] => Array
        (
            [name] => bf_1040242[329]
            [value] => xxxxx
        )

    [10] => Array
        (
            [name] => bf_1040242[28622]
            [value] => 2
        )

    [11] => Array
        (
            [name] => bf_1040242[other][28623]
            [value] => 
        )

    [12] => Array
        (
            [name] => bf_1040242[42283]
            [value] => 1
        )

    [13] => Array
        (
            [name] => bf_1040242[42284][]
            [value] => 2
        )

    [14] => Array
        (
            [name] => bf_1040242[42284][]
            [value] => 3
        )

    [15] => Array
        (
            [name] => bf_1040242[42284][]
            [value] => 4
        )

    [16] => Array
        (
            [name] => bf_1040242[other][42284]
            [value] => Something Else
        )

)

In the above array, the key 'name' represents the structure of individual array in string format and the 'value' holds the value that the array structure needs to be updated to.

This is have managed to get done by using

$extra = []

foreach ($mainArray as $key => $value)
{
    parse_str($value['name'], $tempArr);
    $m = $this->multiArr($k, $value);
    array_push($extra, $m);
}


protected function multiArr($k, $val)
{
    foreach($k as $key => $value)
    {
        if(is_array($value) ) $k[$key] =  $this->multiArr($k[$key], $val);

        if(!is_array($value))
        {
            $k[$key] = (string) $val['value'];
        }
    }
    return $k;
}

$m holds individual array values like

Array
(
    [bf_1040242] => Array
        (
            [other] => Array
                (
                    [42284] => Something Else
                )

        )

)

Using these individual array values i want to create the the Main required array so i used

array_push($extra, $m);

but this adds each $m array below each other instead of updating the way expected above. Below is the way it is coming in my end.


Array
(
    [0] => Array
        (
            [bf_1040242] => Array
                (
                    [326] => Just some Information. Additional Text
                )

        )

    [1] => Array
        (
            [bf_1040242] => Array
                (
                    [17565] => Array
                        (
                            [0] => 2
                        )

                )

        )

    [2] => Array
        (
            [bf_1040242] => Array
                (
                    [17565] => Array
                        (
                            [0] => 1
                        )

                )

        )

    [3] => Array
        (
            [bf_1040242] => Array
                (
                    [17565] => Array
                        (
                            [0] => 3
                        )

                )

        )

    [4] => Array
        (
            [bf_1040242] => Array
                (
                    [other] => Array
                        (
                            [17565] => Testing
                        )

                )

        )

    [5] => Array
        (
            [bf_1040242] => Array
                (
                    [597] => 1
                )

        )

    [6] => Array
        (
            [bf_1040242] => Array
                (
                    [327] => This is some text
                )

        )

    [7] => Array
        (
            [bf_1040242] => Array
                (
                    [328] => asdasd
                )

        )

    [8] => Array
        (
            [bf_1040242] => Array
                (
                    [11880] => wwwww
                )

        )

    [9] => Array
        (
            [bf_1040242] => Array
                (
                    [329] => xxxxx
                )

        )

    [10] => Array
        (
            [bf_1040242] => Array
                (
                    [28622] => 2
                )

        )

    [11] => Array
        (
            [bf_1040242] => Array
                (
                    [other] => Array
                        (
                            [28623] => 
                        )

                )

        )

    [12] => Array
        (
            [bf_1040242] => Array
                (
                    [42283] => 1
                )

        )

    [13] => Array
        (
            [bf_1040242] => Array
                (
                    [42284] => Array
                        (
                            [0] => 2
                        )

                )

        )

    [14] => Array
        (
            [bf_1040242] => Array
                (
                    [42284] => Array
                        (
                            [0] => 3
                        )

                )

        )

    [15] => Array
        (
            [bf_1040242] => Array
                (
                    [42284] => Array
                        (
                            [0] => 4
                        )

                )

        )

    [16] => Array
        (
            [bf_1040242] => Array
                (
                    [other] => Array
                        (
                            [42284] => Something Else
                        )

                )

        )
)

I am not sure if array_push is what i need to use, or something else. Also, is there a cleaner or a more efficient way to this.

Any help is much appreciated, Thanks

2
  • ca you please post a minimal reproducible example at least of the input? and also, bf_1040242[326] is a string? Commented Jul 29, 2020 at 19:44
  • Sure I can. Also that string represents the array format, which i am getting through parse_str Commented Jul 29, 2020 at 19:48

1 Answer 1

1

Normally you'd use array_merge_recursive for this, but it wont preserve named keys, so I wrote a little array_join function to make life easier :)

function array_join($value, &$result) {
    if (!is_array($value)) {
        $result = $value;
        
        return;
    }
    
    foreach ($value as $k => $v) {
        array_join($v, $result[$k]);
    }
}

$result = [];

foreach ($mainArray as $entry)
{
    parse_str($entry['name'] . '=' . $entry['value'], $nameArray);
    array_join($nameArray, $result);
}

We simply call array_join recursively until the value is no longer an array. Notice the & in &$result of array_join. We pass the reference of our current position in the array.

To make full use of parse_str I've added the value aswell by appending =<value>

Working example.

Pro tip for your next post. Use var_export to give us an array, which can be copy pasted as code :)

EDIT

More simple solution with escaped values for "evil" input.

foreach ($mainArray as $entry)
{
    $stringVarArray[] = $entry['name'] . '=' . urlencode($entry['value']);
}
parse_str(implode('&', $stringVarArray), $result);

var_dump($result);

Working example.

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

2 Comments

Thanks @Pilan, This helped me. I used your code and i get everything except for the the keys "42284" and "17565" which is an array of 3 values. But the code return only one value for these keys. Also, next time i'll use var_export. Thanks
@bodi87 Fixed it, found an easier solution along the way, and added some "evil"-value handling.

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.