9

I need to merge several arrays into a single array. The best way to describe what I'm looking for is "interleaving" the arrays into a single array.

For example take item one from array #1 and append to the final array. Get item one from array #2 and append to the final array. Get item two from array #1 and append...etc.

The final array would look something like this:

array#1.element#1 array#2.element#1 . . .

The "kicker" is that the individual arrays can be of various lengths.

Is there a better data structure to use?

2
  • 2
    Please explain further how you expect your result in the case where the arrays have various lengths. Would you stop the interleaving when one of the arrays have reached its last element or do you want the remaining arrays to continue to be interleaved until all arrays have reached their last element? Commented Dec 7, 2009 at 15:07
  • 1
    This question is not terribly clear because we do not have a minimal reproducible example. We cannot be sure if you are seeking "tranposition". If so, the canonical is: Transposing multidimensional arrays in PHP Commented Apr 23, 2022 at 3:06

4 Answers 4

31

for example,

function array_zip_merge() {
  $output = array();
  // The loop incrementer takes each array out of the loop as it gets emptied by array_shift().
  for ($args = func_get_args(); count($args); $args = array_filter($args)) {
    // &$arg allows array_shift() to change the original.
    foreach ($args as &$arg) {
      $output[] = array_shift($arg);
    }
  }
  return $output;
}

// test

$a = range(1, 10);
$b = range('a', 'f');
$c = range('A', 'B');
echo implode('', array_zip_merge($a, $b, $c)); // prints 1aA2bB3c4d5e6f78910
Sign up to request clarification or add additional context in comments.

2 Comments

Great piece of code for sure! If anyone need a detailed step by step explanation how this function works, check out this thread here :)
Note that array_shift is O(n), moves all elements up to fill the gap, traversing the whole array per call. In a nested loop, that's painful from a time complexity standpoint. Better to use array_push which is O(1), then do a one-off reverse of the result at the very end. A counter per array is another option that adds code complexity but is efficient and avoids mutating the input.
3

If the arrays only have numeric keys, here's a simple solution:

$longest = max( count($arr1), count($arr2) );
$final = array();

for ( $i = 0; $i < $longest; $i++ )
{
    if ( isset( $arr1[$i] ) )
        $final[] = $arr1[$i];
    if ( isset( $arr2[$i] ) )
        $final[] = $arr2[$i];
}

If you have named keys you can use the array_keys function for each array and loop over the array of keys instead.

If you want more than two arrays (or variable number of arrays) then you might be able to use a nested loop (though I think you'd need to have $arr[0] and $arr[1] as the individual arrays).

Comments

1

I would just use array_merge(), but that obviously depends on what exactly you do.

This would append those arrays to each other, while elements would only be replaced when they have the same non-numerical key. And that might not be a problem for you, or it might be possible to be solved because of attribute order, since the contents of the first arrays' elements will be overwritten by the later ones.

Comments

0

If you have n arrays, you could use a SortedList, and use arrayIndex * n + arrayNumber as a sort index.

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.