'merging two arrays with specified index

There are two arrays , the second array will always be smaller by 1 from first array. The first array contains the numbers and second array contains the mathematical operators.

 $arr1 = [210,11,12];
 $arr2 = ['-','/'];

the code which i have written is working on this test case only ,but when i increase the number of elements in it. It fails.

 $arr1 = [210,11,12,12];
 $arr2 = ['-','/','/'];

the code i have tried so far..

$arr1 = [210,11,12];
$arr2 = ['-','/'];

$arr3 = [];

for($i=0;$i<count($arr1);$i++){
  if($i == 0){
     $arr3[] = $arr1[0];
 }
 if ($i % 2 != 0) {
    $arr3[] = $arr1[$i];
 }
  else {
      if($i < (count($arr2)-1)){
          $arr3[] = $arr2[$i];
      }else{
         $arr3[] = $arr2[$i-1];
    }

   }
}

    array_push($arr3,end($arr1));
   print_r($arr3);

the expected result will be

$arr3 = [210,'-',11,'/','12','/','12']
php


Solution 1:[1]

Provided, as you say, that the second array is always larger by one element, then this would be a simple way to do it:

function foo(array $p, array $q): array {
    $r = [array_shift($p)];

    foreach ($q as $x) {
        $r[] = $x;
        $r[] = array_shift($p);
    }

    return $r;
}

print_r(
    foo([210,11,12], ['-', '/'])
);

print_r(
    foo([210,11,12,12], ['-','/','/'])
);

https://3v4l.org/F0ud8


If the indices of the arrays are well formed, the above could be simplified to:

function foo(array $p, array $q): array {
    $r = [$p[0]];

    foreach ($q as $i => $x) {
        $r[] = $x;
        $r[] = $p[$i + 1];
    }

    return $r;
}

Solution 2:[2]

You can mix the two arrays together by converting columns to rows with array_map, then merging the rows.

$arr3 = array_merge(...array_map(null, $arr1, $arr2));
array_pop($arr3);

The array_map(null, $arr1, $arr2) expression will result in

[[210, '/'], [11, '/'], [12, '/'], [12, null]]

then, array_merge(...) combines all the inner arrays together into one for the final result.

array_pop will remove the trailing null which is there because of the uneven size of the two arrays, but if you're going to end up imploding this and outputting the results as a math expression, you don't need to do it since that won't show up anyway. In fact, if that is the goal you can just add the implode directly to the expression above.

echo implode(' ', array_merge(...array_map(null, $arr1, $arr2)));

Solution 3:[3]

Loop the first array and use $key =>.
Then you build the new array in the loop and if $arr2 has a value with the same key, add it after the $arr1 value.

$arr1 = [210,11,12,12];
$arr2 = ['-','/','/'];

foreach($arr1 as $key => $val){
    $arr3[] = $val;
    if(isset($arr2[$key])) $arr3[] = $arr2[$key];
}
var_dump($arr3);
//[210, -, 11, /, 12, /, 12]

Solution 4:[4]

I wanted to offer a couple of approaches that do not modify the original array, accommodate the possibility of empty input arrays, and do not use more than one loop.

By prepopulating the result array with the first value from the numbers array, then iterating the operators array, you can avoid making iterated checks of isset().

Code: (Demo) (Demo without iterated array_push() calls)

$numbers = [210, 11, 12];
$operators = ['-', '/'];

$result = (array)($numbers[0] ?? []);
foreach ($operators as $i => $operator) {
    array_push($result, $operator, $numbers[++$i]);
}
var_export($result);

or with array_reduce():

var_export(
    array_reduce(
        $operators,
        function($result, $operator) use($numbers) {
            static $i = 0;
            array_push($result, $operator, $numbers[++$i]);
            return $result;
        },
        (array)($numbers[0] ?? [])
    )
);

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Yoshi
Solution 2
Solution 3 Don't Panic
Solution 4 mickmackusa