0
\$\begingroup\$

I have a function that's doing this correctly, but I feel as though this can be done (possibly) with minimal code, with recursion, but I'm just wracking my brain. Basically I have JSON that gets decoded to an array. What I want to do is turn this:

{
  "parentView": {
    "childViews": [
      {
        "type": "container-fluid",       
        "childViews": [        
          {
            "type": "row",  
            "childViews": [            
              {
                "type": "slider"
              },
              {
                "type": "slider"
              }
            ]            
          }        
        ]
      }
    ]    
  }
}

Into this:

{
  "parentView": {
    "childViews": [
      {
        "type": "controller",
        "childViews": [
          {
            "type": "container-fluid",       
            "childViews": [        
              {
                "type": "controller",
                "childViews": [
                  {
                    "type": "row",
                    "childViews": [            
                      {
                        "type": "controller",
                        "childViews": [
                          {
                            "type": "slider"
                          }
                        ]
                      },
                      {
                        "type": "controller",
                        "childViews": [
                          {
                            "type": "slider"
                          }
                        ]
                      }
                    ]            
                  }        
                ]
              }
            ]
          }
        ]
      }
    ]    
  }
}

Here is the code I am using to make it work how I need. I am just looking for a cleaner method:

function createControls($parentView)
{
    $newArr = $parentView;

    foreach ($parentView as $k => $v) {
        $newArr[$k] = [
            'type' => 'control',
            'childViews' => $v
        ];

        if ($v['childViews']) {
            foreach ($v['childViews'] as $kk => $vv) {
                $newArr[$k]['childViews']['childViews'] = [
                    'type' => 'control',
                    'childViews' => $vv
                ];

                if ($vv['childViews']) {
                    foreach ($vv['childViews'] as $_k => $_v) {
                        $newArr[$k]['childViews']['childViews']['childViews']['childViews'][$_k] = [
                            'type' => 'control',
                            'childViews' => $_v
                        ];
                    }
                }
            }
        }
    }

    return $newArr;
}

$newArr = createControls($arr['parentView']['childViews']);
$arr['parentView']['childViews'] = $newArr;

Thanks in advance! Kind regards!

\$\endgroup\$
  • \$\begingroup\$ Welcome to Code Review. It seems that the question may greatly benefit from a more precise problem statement. \$\endgroup\$ – vnp Dec 18 '18 at 23:29
0
\$\begingroup\$

You can try something like this, note that it is untested:

<?php
function createControls($parentView) {
    $newArr = $parentView;
    foreach ($parentView as $k => $v) {
        $newArr[$k] = ['type' => 'control'];
        if (isset($v['childViews'])) {
            $v = createControls($v['childViews']);
        }
        $newArr[$k]['childViews'] = $v;
    }
    return $newArr;
}
?>

This function uses reccursion to do the same as your code above. It takes one array of Key Value pairs and reassigns the values to wrap the old values into an array with the following format:

array ( 'type' => 'control', 'childViews' => $oldValue );

Basically, instead of nesting a new loop each time the depth of your input array changes like in your function above this function will just pass the old childValues back into itself and assign the result as the new childValues array.

\$\endgroup\$
  • \$\begingroup\$ Thanks for the reply. While I believe I tried something like this before just adding a bunch of foreach statements, everything that should have control gets wrapped with control but the contents get lost (container-fluid, row), and so the last items are the ones that still retain data (childViews type > control, subviews > slider). This is definitely close. I'll try to rework this, or find out why the data is not retaining in the parent items. (example output from the code above) codeshare.io/GbYNYA \$\endgroup\$ – Aaron Olin Dec 18 '18 at 19:07
  • \$\begingroup\$ Ha! I just added an answer, and yours was based on the same thing. Thanks again for your help Kevin! Much appreciated \$\endgroup\$ – Aaron Olin Dec 18 '18 at 19:22
0
\$\begingroup\$

Thanks for your help, I believe this is the solution to the problem.

function createControls($parentView) {
    $newArr = $parentView;
    foreach ($parentView as $k => &$v) {
        $newArr[$k] = [
            'type' => 'control',
            'childViews' => $v
        ];

        if (isset($v['childViews'])) {
            $v['childViews'] = createControls($v['childViews']);
        }

        $newArr[$k]['childViews'] = [$v];
    }
    return $newArr;
}

$newArr = createControls($arr['parentView']['childViews']);

$arr['parentView']['childviews'] = $newArr;

Much appreciated for the help kevincorrigan, thanks for getting me out of this fog! :)

\$\endgroup\$

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.