0

I got stuck somehow on the following problem: What I want to achieve is to merge the following arrays based on key :

{"Entities":{"submenu_id":"Parents","submenu_label":"parents"}}
{"Entities":{"submenu_id":"Insurers","submenu_label":"insurers"}}
{"Users":{"submenu_id":"New roles","submenu_label":"newrole"}}
{"Users":{"submenu_id":"User - roles","submenu_label":"user_roles"}}
{"Users":{"submenu_id":"Roles - permissions","submenu_label":"roles_permissions"}}
{"Accounting":{"submenu_id":"Input accounting data","submenu_label":"new_accounting"}}

Which needs to output like this:

[{"item_header":"Entities"}, 
 {"list_items" :
    [{"submenu_id":"Parents","submenu_label":"parents"}, 
    {"submenu_id":"Insurers","submenu_label":"insurers"}]
}]
[{"item_header":"Users"}, 
 {"list_items" : 
    [{"submenu_id":"New roles","submenu_label":"newrole"}
    {"submenu_id":"User - roles","submenu_label":"user_roles"}
    {"submenu_id":"Roles - permissions","submenu_label":"roles_permissions"}]
}]
[{"item_header":"Accounting"}, 
 {"list_items" :
    [{"submenu_id":"Input accounting data","submenu_label":"new_accounting"}]
}]

I have been trying all kinds of things for the last two hours, but each attempt returned a different format as the one required and thus failed miserably. Somehow, I couldn't figure it out.
Do you have a construction in mind to get this job done?
I would be very interested to hear your approach on the matter.

Thanks.

3
  • How about you use HashMap style of storage? Against each key store an array which stores the values. Comment back in case you want the code. Commented Jan 26, 2014 at 17:15
  • @AkshatSinghal A piece of code to help me on the way would be much appreciated. I tried many loops and temporary key-value storage combinations, but not one of them resulted in the format required. Commented Jan 26, 2014 at 17:19
  • Check the solution posted; comment back in case you require code for iterating over the new array. Commented Jan 26, 2014 at 17:34

4 Answers 4

1
$input = array(
    '{"Entities":{"submenu_id":"Parents","submenu_label":"parents"}}',
    '{"Entities":{"submenu_id":"Insurers","submenu_label":"insurers"}}',
    '{"Users":{"submenu_id":"New roles","submenu_label":"newrole"}}',
    '{"Users":{"submenu_id":"User - roles","submenu_label":"user_roles"}}',
    '{"Users":{"submenu_id":"Roles - permissions","submenu_label":"roles_permissions"}}',
    '{"Accounting":{"submenu_id":"Input accounting data","submenu_label":"new_accounting"}}',
);

$input = array_map(function ($e) { return json_decode($e, true); }, $input);

$result = array();
$indexMap = array();
foreach ($input as $index => $values) {
    foreach ($values as $k => $value) {
        $index = isset($indexMap[$k]) ? $indexMap[$k] : $index;
        if (!isset($result[$index]['item_header'])) {
            $result[$index]['item_header'] = $k;
            $indexMap[$k] = $index;
        }
        $result[$index]['list_items'][] = $value;
    }
}
echo json_encode($result);
Sign up to request clarification or add additional context in comments.

Comments

0

Here you are!
In this case, first I added all arrays into one array for processing.
I thought they are in same array first, but now I realize they aren't. Just make an empty $array=[] then and then add them all in $array[]=$a1, $array[]=$a2, etc...

   $array = '[{"Entities":{"submenu_id":"Parents","submenu_label":"parents"}},
   {"Entities":{"submenu_id":"Insurers","submenu_label":"insurers"}},
   {"Users":{"submenu_id":"New roles","submenu_label":"newrole"}},
   {"Users":{"submenu_id":"User - roles","submenu_label":"user_roles"}},
   {"Users":{"submenu_id":"Roles - permissions","submenu_label":"roles_permissions"}},
   {"Accounting":{"submenu_id":"Input accounting data","submenu_label":"new_accounting"}}]';

   $array = json_decode($array, true);


    $intermediate = []; // 1st step

    foreach($array as $a)
    {
       $keys = array_keys($a);
       $key = $keys[0]; // say, "Entities" or "Users"
       $intermediate[$key] []= $a[$key];
    }

    $result = []; // 2nd step

    foreach($intermediate as $key=>$a)
    {
       $entry = ["item_header" => $key, "list_items" => [] ];
       foreach($a as $item) $entry["list_items"] []= $item;
       $result []= $entry;
    }

    print_r($result);

Comments

0

I would prefer an OO approach for that.

First an object for the list_item:

{"submenu_id":"Parents","submenu_label":"parents"}

Second an object for the item_header:

{"item_header":"Entities", "list_items" : <array of list_item> }

Last an object or an array for all:

{ "Menus: <array of item_header> }

And the according getter/setter etc.

1 Comment

Thanks for the tip. I will give that some more thought and trial-error for some time.
0

The following code will give you the requisite array over which you can iterate to get the desired output.

$final_array = array();  
foreach($array as $value) { //assuming that the original arrays are stored inside another array. You can replace the iterator over the array to an iterator over input from file       
    $key  =  /*Extract the key from the string ($value)*/
    $existing_array_for_key = $final_array[$key];
    if(!array_key_exists ($key , $final_array)) {
        $existing_array_for_key = array();
    }
    $existing_array_for_key[count($existing_array_for_key)+1] = /*Extract value from the String ($value)*/
    $final_array[$key] = $existing_array_for_key;
}

Comments

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.