简体   繁体   中英

How to merge the output of two associative arrays with no unique keys?

I've got the feeling that I get stuck with something that seemed to be a trivial task. Please take a look at the $data array. This is the data skeleton for a multilevel menue. $data['name'] contains the names for the given menue points/buttons and $data['url'] the corresponding links. The array dimensions $data['name'] and $data['url'] are perfectly in sync - with exact same nodes, same element count and so on.

Having this I started to write a simple output function - with names only first. I know the code isn't pretty but it works. Beat me but my mind aches when mentioning recursion ;) Nevertheless my primitive way leads to proper output. In the second step I needed to add the url information corresponding to the names/buttons but this is where I fail and begun to feel dumb.

While iterating through $data['name'] I need a pointer for the current element and would use it to get the corresponding url from $data['url'] but nope - this is an associative array so this way leads to the dead end. The keys aren't unique by the way ... this would be to easy sigh This array is only a shortened version of the original one which is generated from a 150 pages long word document that is still growing and changing.

Any ideas how to output button-names + corresponding url's ? I placed the working code on codepad.org for fiddling around.

My array:

<?PHP    

$data = array (    
  'name' =>     
  array (    
    'basics' =>     
    array (    
      0 => 'about',    
      1 => 'why_do_i_need_it',    
      2 => 'institutions',    
      3 => 'agencys',    
      4 => 'impact',    
      5 => 'failing_this_test',    
      6 => 'evaluation_criteria',    
      7 => 'evaluation_range',    
      8 => 'reissue_request',    
      9 => 'procedure',    
      'procedure' =>     
      array (    
        0 => 'psych',    
        'psych' =>     
        array (    
          0 => 'test_1',    
          1 => 'test_2',    
          2 => 'test_3',    
          3 => 'test_4',    
          4 => 'test_5',    
        ),    
        'med' =>     
        array (    
          0 => 'examination',    
          1 => 'exploration',    
          2 => 'observation',    
        ),    
      ),    
      10 => 'report',    
      11 => 'revision',    
      12 => 'evaluation',    
      13 => 'report_structure',    
      14 => 'charges',    
      15 => 'sample_test',    
    ),    
    'drugs' =>     
    array (    
      0 => 'introduction',    
      1 => 'requirements',    
      'requirements' =>     
      array (    
        0 => 'sincerity',    
        1 => 'excuses',    
        2 => 'insight',    
        3 => 'change',    
        4 => 'stability',    
      ),    
      2 => 'procedure',    
      3 => 'diagnostics',    
      'diagnostics' =>     
      array (    
        0 => 'addiction',    
        1 => 'advanced_level',    
        2 => 'dangers',    
        3 => 'sample_drugtest',    
      ),    
      4 => 'the_day_one',    
      5 => 'background',    
      6 => 'today',    
      7 => 'intake',    
      8 => 'screenings',    
      'screenings' =>     
      array (    
        0 => 'analysys',    
        1 => 'element',    
      ),    
    ),    



  'url' =>     
  array (    
    'basics' =>     
    array (    
      0 => 'basics.about',    
      1 => 'basics.why_do_i_need_it',    
      2 => 'basics.institutions',    
      3 => 'basics.agencys',    
      4 => 'basics.impact',    
      5 => 'basics.failing_this_test',    
      6 => 'basics.evaluation_criteria',    
      7 => 'basics.evaluation_range',    
      8 => 'basics.reissue_request',    
      9 => 'basics.procedure',    
      'procedure' =>     
      array (    
        0 => 'basics.procedure.psych',    
        'psych' =>     
        array (    
          0 => 'basics.procedure.psych.test_1',    
          1 => 'basics.procedure.psych.test_2',    
          2 => 'basics.procedure.psych.test_3',    
          3 => 'basics.procedure.psych.test_4',    
          4 => 'basics.procedure.psych.test_5',    
        ),    
        'med' =>     
        array (    
          0 => 'basics.procedure.med.examination',    
          1 => 'basics.procedure.med.exploration',    
          2 => 'basics.procedure.med.observation',    
        ),    
      ),    
      10 => 'basics.report',    
      11 => 'basics.revision',    
      12 => 'basics.evaluation',    
      13 => 'basics.report_structure',    
      14 => 'basics.charges',    
      15 => 'basics.sample_test',    
    ),    
    'drugs' =>     
    array (    
      0 => 'drugs.introduction',    
      1 => 'drugs.requirements',    
      'requirements' =>     
      array (    
        0 => 'drugs.requirements.sincerity',    
        1 => 'drugs.requirements.excuses',    
        2 => 'drugs.requirements.insight',    
        3 => 'drugs.requirements.change',    
        4 => 'drugs.requirements.stability',    
      ),    
      2 => 'drugs.procedure',    
      3 => 'drugs.diagnostics',    
      'diagnostics' =>     
      array (    
        0 => 'drugs.diagnostics.addiction',    
        1 => 'drugs.diagnostics.advanced_level',    
        2 => 'drugs.diagnostics.dangers',    
        3 => 'drugs.diagnostics.sample_drugtest',    
      ),    
      4 => 'drugs.the_day_one',    
      5 => 'drugs.background',    
      6 => 'drugs.today',    
      7 => 'drugs.intake',    
      8 => 'drugs.screenings',    
      'screenings' =>     
      array (    
        0 => 'drugs.screenings.analysys',    
        1 => 'drugs.screenings.element',    
      ),    
    ),    
  ),    
 )    
);    

My code:

//-----------------------------------------------------------    

    menueOutput($data);    


//-----------------------------------------------------------    

function menueOutput($str)    
{    
foreach($str AS $index =>$atom)    
{                                                          
    if(is_array($atom))    
    {    
        echo "\n\r>".$index;    

        foreach($atom AS $index2 => $atom2)    
        {    
            if(is_array($atom2))    
            {            
            echo "\n\r>>".$index2;    

                foreach($atom2 AS $index3 => $atom3)    
                {    
                    if(is_array($atom3))    
                    {        
                        echo "\n\r>>>".$index3;    

                        foreach($atom3 AS $index4 => $atom4)    
                        {    
                            if(is_array($atom4))    
                            {    
                                echo "\n\r>>>>".$index4;    

                                foreach($atom4 AS $index5 => $atom5)    
                                {    
                                    if(is_array($atom5))    
                                    {    
                                        echo "\n\r>>>>>".$index5;    
                                        foreach($atom5 AS $index6 => $atom6)    
                                        {    
                                            echo "\n\r------".$atom6;    
                                        }    
                                    }    
                                    else    
                                        echo "\n\r-----".$atom5;    
                                }        
                            }    
                            else    
                                echo "\n\r----".$atom4;    
                        }    
                    }    
                    else    
                    {    
                        echo "\n\r---".$atom3;    
                    }    
                }                
            }    
            else    
            {    
                echo "\n\r--".$atom2;    
            }    
        }    
    }    
    else    
    {    
        echo "\n\r".$atom;    
    }        
 }    
}    


//-----------------------------------------------------------     

UPDATE:

I'm also considering to merge the partial arrays by parallel loops. I found this MULTIPLEITERATOR EXAMPLE that may be what I need (if I'll be lazy). Otherwise I'll be forced to refactor my data which can be painful. If I do this Revent answer would become very useful.

What I do with menu systems is have a multi-dimensional array with all the info for one menu item in one element of the array. For example

$menu = array(
   'top_level' => array(
      0 => array('name'=>'Item 1','url' =>'Url 1', ...),
      1 => array('name'=>'Item 2','url' =>'Url 2', ...)
    ),
    'sub_level' => array(
      0 => array('name'=>'Item 1','url' =>'Url 1', ...),
      1 => array('name'=>'Item 2','url' =>'Url 2', ...)
    ),
    ...
);

I go through the pain initially of fetching my data and putting into an array that is easy to output to the screen.

Without unique ids in your arrays, you are left to match them by position in the array, which may or may not be reliable. If you have control over the data going into them I would highly recommend rebuilding your array into something that makes more sense. If you have over 150 items then you will need to be as efficient as you can with your array design.

UPDATE: Here is how I would probably structure the data:

<?php
$data = array (
  'basics' => array ('name'=>'basics', url=>'basics', 'children'=> 
      array (
         0 => array('name'=>'about', 'url'=>'basics.about'),
         1 => array('name'=>'why_do_i_need_it', 'url'=>'basics.why_do_i_need_it'),
         2 => array('name'=>'institutions', 'url'=>'basics.institutions'),
         3 => array('name'=>'agencys', 'url'=>'basics.agencys'),
         4 => array('name'=>'impact', 'url'=>'basics.impact'),
         5 => array('name'=>'failing_this_test', 'url'=>'basics.failing_this_test'),
         6 => array('name'=>'evaluation_criteria', 'url'=>'basics.evaluation_criteria'),
         7 => array('name'=>'evaluation_range', 'url'=>'basics.evaluation_range'),
         8 => array('name'=>'reissue_request', 'url'=>'basics.reissue_request'),
         9 => array('name'=>'procedure', 'url'=>'basics.procedure', 'children' =>
            array(
               0 => array('name'=>'psych', 'url'=>'psych', 'children'=>
                  array(
                     0 => array('name'=>'test_1', 'url'=>'test_1'),
                     1 => array('name'=>'test_2', 'url'=>'test_2'),
                     2 => array('name'=>'test_3', 'url'=>'test_3'),
                     3 => array('name'=>'test_4', 'url'=>'test_4'),
                     4 => array('name'=>'test_5', 'url'=>'test_5')
                  )
               ),
               1 => array('name'=>'med', 'url'=>'med', 'children'=>
                  array(
                     0 => array('name'=>'examination', 'url'=>'examination'),
                     1 => array('name'=>'exploration', 'url'=>'exploration'),
                     2 => array('name'=>'observation', 'url'=>'observation')
                  )
               )
            )
         ),
         ...
      )
    )
  );
?>

As you can see, each menu item stores both the name and the url. If there are children, you simply add a third element to that array with the children in a similar array. Your PHP code to extract the data loops should be greatly simplified as shown below:

foreach ( $data as $top )
{
   echo '<br><a href="'.$top['url'].'">'.$top['name'].'</a>';   // print out the menu item

   if ( array_key_exists('children', $top) )
   {
      foreach ($top['children'] as $level2)
      {
         echo '<br>&nbsp;-&nbsp;<a href="'.$level2['url'].'">'.$level2['name'].'</a>';   // print out the children
         if ( array_key_exists('children', $level2) )
         {
            foreach ($level2['children'] as $level3)
            {
               echo '<br>&nbsp;&nbsp;&nbsp;-&nbsp;<a href="'.$level3['url'].'">'.$level3['name'].'</a>';   // print out the grandchildren
               if ( array_key_exists('children', $level3) )
               {
                  // process the greatgrandchildren, etc.
               }
            }
         }
      }
   }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM