4

I have two arrays:

A = [1, 2, 3, 4]
B = ['a', 'b', 'c', 'd']

I want to merge them into tuples (A, B) in an one-dimensional array:

C = [1, 'a', 2, 'b', 3, 'c', 4, 'd']

Is there some native function in PHP that lets you interpolate two arrays this way? If not, would a loop be the most effective and eficient way to do this?

The number of elements of A will always be the same of B.

Note: If it helps, in the context of my specific needs, array A can be summarized as a single value (since the value will be the same for all values in B).

A = 1
B = ['a', 'b', 'c', 'd']
C = [1, 'a', 1, 'b', 1, 'c', 1, 'd']
Renato Rodrigues
  • 1,038
  • 1
  • 18
  • 35
  • @Maximus2012 `array_merge()` would just concatenate (`C = A + B`). I want `C = A[0] + B[0] + A[1] + C[1]` – Renato Rodrigues Aug 01 '13 at 17:14
  • If only pushing a single static value between each element of the other array, then see the answers @ [Push static value into another array at every nth position](https://stackoverflow.com/q/13901043/2943403) – mickmackusa Sep 03 '22 at 06:53

4 Answers4

4

Loops are OK in this case, since PHP does not have a native function to interleave 2 arrays, but this is a nice way to solve the problem:

function interleave($array1, $array2) {
    $result = array();
    array_map(function ($e1, $e2) use (&$result) {
        array_push($result, $e1, $e2);
    }, $array1, $array2);
    return $result;
}
cschorn
  • 1,191
  • 10
  • 11
  • You need `use ($result)` there, so that the `$result` can be accessed from within the anonymous function. – Paul Aug 01 '13 at 17:22
  • 1
    + Concise. Although since short circuiting the `array_map()` callback though, you might as well just loop. – Jason McCreary Aug 01 '13 at 17:27
  • @JasonMcCreary right, I looked at it from a functional perspective first ... forest, trees and all that. Although `array_map` works regardless of the length or index types of the arguments. – cschorn Aug 01 '13 at 17:33
3

I don't know if there is any built-in mapping function that makes this easier, but this is a simple, naive implementation.

$a = array(1,2,3,4);
$b = array('a','b','c','d');

function array_interpolate($a, $b) {
    if (sizeof($a) != sizeof($b))
        throw new Exception('Arrays must be of same size');

    $result = array();
    for ($i = 0, $l = sizeof($a); $i < $l; $i++) {
        $result[2*$i] = $a[$i];
        $result[2*$i+1] = $b[$i];
    }
    return $result;
}

$res = array_interpolate($a, $b);
print_r($res);

The above returns

Array
(
    [0] => 1
    [1] => a
    [2] => 2
    [3] => b
    [4] => 3
    [5] => c
    [6] => 4
    [7] => d
)
kba
  • 19,333
  • 5
  • 62
  • 89
2
$C = call_user_func_array('array_merge', call_user_func_array('array_map', array(NULL, $A, $B)));
Expedito
  • 7,771
  • 5
  • 30
  • 43
1

Since in PHP arrays are implemented as hash tables (Hash table on wikipedia), you won't be able to achieve your goal faster then looping through array.

Here is a simplest example:

function interpolate(array $a,array $b) {
    $result = array();
    for($i = 0; $i < count($a); $i++) {
        $result[] = $a[$i];
        $result[] = $b[$i];
    }
    return $result;
}
Dima Zbarski
  • 275
  • 2
  • 4
  • Since you seem concerned with speed, it's worth mentioning that you check the array length of `$a` for each iteration - this can be a costly and unnecessary operation, you should check the length once and reuse the result throughout the loop: `for($i = 0, $l = count($a); $i < $l ...`. – kba Aug 01 '13 at 18:07
  • The question was about "most effective and efficient way". About unnecessary call to count() each iteration - it won't actually happen because interpreter will optimize it anyway. IMO sometimes it's better to leave some things to interpreter to optimize to make code easier to understand and shorter. – Dima Zbarski Aug 01 '13 at 21:10
  • Do you have any sources on that optimisation? Deciding making make a single `count($a)` is undecidable in some cases, so I don't think the compiler will do that. I know it won't in Java, for instance. – kba Aug 02 '13 at 02:09
  • 1
    I already was writing that this is the simplest optimization that interpreter can do. But out of curiosity I did a test and found that after all you are right. When taking call to `count()` out of `for` condition script runs much faster (x2 faster in case of copying array with 1M integers). – Dima Zbarski Aug 02 '13 at 19:12
  • As I suspected. If you're curious about why the compiler doesn't do this, you should read about static program analysis, undecidability, and the Halting Problem. – kba Aug 02 '13 at 19:53