0

So I have an array as follows. I want to merge all of these into one array of key => value.

Input :

$logTypes = array(
    'user_management'   => array(
        1001 => 'A new user was added',
        1002 => '#user_name# accessed user management',
        1003 => 'Created',
        1004 => 'Edited/Updated'),
    'report_management' => array(
        2001 => '#user_name# Added a new report',
        2002 => '#user_name# viewed "edit history" for the report #report_name#',
    ),
);

Required Output :

array (
  1001 => 'A new user was added',
  1002 => '#user_name# accessed user management',
  1003 => 'Created',
  1004 => 'Edited/Updated',
  2001 => '#user_name# Added a new report',
  2002 => '#user_name# viewed "edit history" for the report #report_name#',
)

I tried various permutations of array_merge, array_map, array_values but they just don't work as a whole, like some of them manage to merge but re-index the keys etc. etc.

My attempts:

logTypes = call_user_func('array_merge', array_values(self::$logTypes));

$logTypes = call_user_func('array_push', self::$logTypes);

$logTypes = call_user_func_array('array_merge', self::$logTypes);

$logTypes = array_values(array_values(self::$logTypes));

$array = array_map('current', self::$logTypes);

$merged = array_merge(...self::$logTypes);

Finally I had to resort to what I was trying to avoid all along, looping through each array :l

$plain_array = array();
foreach (self::$logTypes as $types) {
    $plain_array += $types;
}

It works, so now my question is that, Is there any other way to achieve the desired result, using the above array_* functions ?

If I may add, may the shortest solution win!! :)

Mohd Abdul Mujib
  • 13,071
  • 8
  • 64
  • 88
  • You could try `array_replace` function ```$plain_array = array(); foreach ($logTypes as $types) { $plain_array = array_replace($plain_array, $types); }``` – FallDi Jul 24 '18 at 09:46
  • Thanks for the suggestion, I am looking for **not having to loop manually** through the original array. – Mohd Abdul Mujib Jul 24 '18 at 09:48
  • 1
    Non loop solution ```array_reduce( $logTypes, function($carry, $types) { $carry = array_replace($carry, $types); return $carry; }, [] );``` – FallDi Jul 24 '18 at 09:50
  • Thanks @FallDi your solution does work, I even shortened it `array_reduce(self::$logTypes, function($carry, $types) { return $carry += $types; }, [])` – Mohd Abdul Mujib Jul 24 '18 at 10:00

2 Answers2

1

You can do it like this:

array_reduce($logTypes, function($carry, $item) {
    return $carry + $item;
}, []);

output:

array (
  1001 => 'A new user was added',
  1002 => '#user_name# accessed user management',
  1003 => 'Created',
  1004 => 'Edited/Updated',
  2001 => '#user_name# Added a new report',
  2002 => '#user_name# viewed "edit history" for the report #report_name#',
)

Source: http://php.net/manual/en/function.array-reduce.php

diegowc
  • 455
  • 2
  • 14
0

Try this:

$new_array = $logTypes['user_management'] + $logTypes['report_management'];

PHP doc

If you want to append array elements from the second array to the first array while not overwriting the elements from the first array and not re-indexing, use the + array union operator

nmr
  • 358
  • 4
  • 10