bodi87
bodi87

Reputation: 551

PHP Modify multidimensional array to update values rather than adding to the end

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

Upvotes: 0

Views: 108

Answers (1)

SirPilan
SirPilan

Reputation: 4857

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.

Upvotes: 1

Related Questions