0

I have an array that is created from a CSV file that I would like use the first value in each array as the key and combine the arrays with the same first value in an array. All arrays with [Parent] => top should be combined into an array [top] => Array. The below is a sample of what is in the CSV file. There is an unknown amount of MenuItem's. The only known is that the menus only go 3 levels deep Top>Sub1>Sub2. Also the MenuItems for the top menu can can change. I'm going to need something that can look at the [Parent] key in the first array and if it equals "top" then create an array based on the key [MenuItem], then any other array where [Parent]=Programs then that [MenuItem] & [URL] will be added to the Programs array.

Array
(
    [0] => Array
        (
            [Parent] => top
            [MenuItem] => Home
            [URL] => /
        )

    [1] => Array
        (
            [Parent] => top
            [MenuItem] => Programs
            [URL] => /programs/
        )

    [2] => Array
        (
            [Parent] => Programs
            [MenuItem] => Programs Sub1
            [URL] => /programs/sub1/
        )

    [3] => Array
        (
            [Parent] => Programs
            [MenuItem] => Programs Sub2
            [URL] => /programs/sub2/
        )

    [4] => Array
        (
            [Parent] => Programs
            [MenuItem] => Programs Sub3
            [URL] => /programs/sub3/
        )
)

Result should be:

Array
(
    [top] => Array
        (
            [0] => Array
                (
                     [MenuItem] => Home
                     [URL] => /
                )
            [1] => Array
                (
                    [MenuItem] => Programs
                    [URL] => /programs/
                    [Programs] => Array
                        (
                            [0] => Array
                                (
                                    [MenuItem] => Programs Sub1
                                    [URL] => /programs/sub1/
                                )
                            [1] => Array
                                (
                                    [MenuItem] => Programs Sub2
                                    [URL] => /programs/sub2/
                                )
                            [2] => Array
                                (
                                    [MenuItem] => Programs Sub3
                                    [URL] => /programs/sub3/
                                )
                )

Example of the Menu

Home    Programs
            Programs Sub1
            Programs Sub2
            Programs Sub3
BrianC987
  • 167
  • 1
  • 14
  • Should the `Programs` array in your output have 3 entries? Also how do you pair the `[Parent] => programs` with `[MenuItem] => Programs` as the case is different... – Nick Apr 06 '19 at 03:41
  • Nick, Yes, the `Programs` array should have 3 entries. I made the edit to show that. I'm not sure I understand the second question. I have added an example of the menu. – BrianC987 Apr 06 '19 at 04:49
  • There is no posted coding attempt. Have you tried researching any of the many pre-existing recursive solutions on StackOverflow? Such as: https://stackoverflow.com/q/19600362/2943403 – mickmackusa Apr 07 '19 at 03:30

1 Answers1

1

Try this,

function loop($arr, $parent, &$result) {
    $temp = array_filter($arr, function($t) use ($parent) {
        return $t['Parent'] == $parent;
    });
    foreach ($temp as $t) {
        $parent = $t['MenuItem'];
        if (array_search($parent, array_column($arr, 'Parent')) !== FALSE) {
            $x = &$result[$t['Parent']][];
            $x = array_slice($t, 1);
            loop($arr, $parent, $x);
        }else{            
            $result[$t['Parent']][] = array_slice($t, 1);
        }
    }
}

$arr = Array
    (Array
        (
        'Parent' => 'top',
        'MenuItem' => 'Home',
        'URL' => '/',
    ),
    Array(
        'Parent' => 'top',
        'MenuItem' => 'Programs',
        'URL' => '/programs/',
    ),
    Array(
        'Parent' => 'Programs',
        'MenuItem' => 'Programs Sub1',
        'URL' => '/programs/sub1/',
    ),
    Array(
        'Parent' => 'Programs',
        'MenuItem' => 'Programs Sub2',
        'URL' => '/programs/sub2/',
    ),
    Array(
        'Parent' => 'Programs',
        'MenuItem' => 'Programs Sub3',
        'URL' => '/programs/sub3/',
    ),
    Array(
        'Parent' => 'Programs Sub2',
        'MenuItem' => 'Programs Sub2 1',
        'URL' => '/programs/sub2/1',
    ),
    Array(
        'Parent' => 'Programs Sub2',
        'MenuItem' => 'Programs Sub2 2',
        'URL' => '/programs/sub2/2',
    )
);

$result = [];

$parent = $arr[0]['Parent'];

loop($arr, $parent, $result);

var_dump($result);

It works for menus of any depth, loop() is a recursive function.

Shoyeb Sheikh
  • 2,659
  • 2
  • 10
  • 19