9

array_chunk splits an array into multiple arrays using a chunk size to make the cuts.

What if I have an array of arrays of values, and I just want one big array of values?

I could use array_merge, but that would require me to enumerate all the sub-arrays, of which there may be a variable number.

For now, my solution is:

foreach($input as $tmp) {foreach($tmp as $val) {
    ...
}}

But that's kind of messy and only works because I want to use the values. What if I wanted to store the array somewhere?

EDIT: The input is coming from a set of <select multiple> boxes, used to select items from multiple categories. Each item has a globally unique (among items) ID, so I just want to combine the input into a single array and run through it.

The input might look like:

[[4,39,110],[9,54,854,3312,66950],[3]]

Expected output:

[4,39,110,9,54,854,3312,66950,3]

or:

[3,4,9,29,54,110,854,3312,66950]
Niet the Dark Absol
  • 320,036
  • 81
  • 464
  • 592

5 Answers5

6

Code:

$array = [[4,39,110], [9,54,854,3312,66950], [3]];
$array = call_user_func_array('array_merge', $array);

print_r($array);

Result:

Array
(
    [0] => 4
    [1] => 39
    [2] => 110
    [3] => 9
    [4] => 54
    [5] => 854
    [6] => 3312
    [7] => 66950
    [8] => 3
)
Viltaly Artemev
  • 121
  • 1
  • 3
5

While PHP doesn't have a built in method to flatten an array, you can achieve the same thing using array_reduce and array_merge. Like this:

$newArray = array_reduce($array, function ($carry, $item) {
    return array_merge($carry, $item);
}, []);

This should work as an inverse operation to array_chunk.

Darren
  • 111
  • 2
  • 3
5

The "..." operator which turns an array into an arguments list can come in very handy in this case (https://www.php.net/manual/en/functions.arguments.php#functions.variable-arg-list).

The inverse of array_chunk() could be this:

array_merge(...$chunks);

Example:

print_r(array_merge(...[[0,1,2],[3,4,5]]));

Output:

Array
(
   [0] => 0
   [1] => 1
   [2] => 2
   [3] => 3
   [4] => 4
   [5] => 5
)
gustre
  • 81
  • 1
  • 4
4

Lifted from the PHP documentation on array_values:

/** 
 * Flattens an array, or returns FALSE on fail. 
 */ 
function array_flatten($array) { 
  if (!is_array($array)) { 
    return FALSE; 
  } 
  $result = array(); 
  foreach ($array as $key => $value) { 
    if (is_array($value)) { 
      $result = array_merge($result, array_flatten($value)); 
    } 
    else { 
      $result[$key] = $value; 
    } 
  } 
  return $result; 
}

PHP has no native method to flatten an array .. so there you go.

Explosion Pills
  • 188,624
  • 52
  • 326
  • 405
  • Hmm... Good answer, but I guess I'd be better off efficiency-wise to just keep what I'm doing, at least for now. – Niet the Dark Absol May 15 '12 at 12:24
  • His answer is as efficient as yours, just a little more text and it can do multiple levels of arrays. Note however, it will override duplicate keys (see http://codepad.org/JPaFgYRt) – Zombaya May 15 '12 at 12:26
  • As efficient, yes, but if I then have to loop through the result to do the processing, it's not worth it. This answers the question in that it's a good solution for collapsing an array, but if it's being used right there it's just overhead. – Niet the Dark Absol May 15 '12 at 12:54
2

Sorry if i am wrong, but if we will take same name in multiple select groups then it will produce an expected array.

<?php
echo '<pre>';
print_r($_POST['cat']);
?>
<form method="post">
<select name="cat[]" multiple="multiple">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>

<select name="cat[]" multiple="multiple">
<option value="22">2</option>
<option value="33">3</option>
</select>

<select name="cat[]" multiple="multiple">
<option value="111">111</option>
<option value="222">222</option>
<option value="333">333</option>
<option value="444">444</option>
</select>
<input name="" type="submit" />
</form>

Output:

Array
(
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => 4
    [4] => 22
    [5] => 33
    [6] => 222
)
VibhaJ
  • 2,256
  • 19
  • 31
  • This will, in fact, avoid the extra server-side handling. If it is not necessary to know which category/select the id came from, this is the wisest choice. @Niet – mickmackusa Feb 09 '20 at 01:40
  • Nitpicking: there is no need to declare the option ` value` when it is the same as the option text. – mickmackusa Feb 09 '20 at 02:47