0

I have the following Arrays:

$front = array("front_first","front_second");
$inside = array("inside_first", "inside_second", "inside_third");
$back = array("back_first", "back_second", "back_third","back_fourth");

what I need to do is combine it so that an output would look like this for the above situation. The output order is always to put them in order back, front, inside:

$final = array(
"back_first",
"front_first",
"inside_first",
"back_second",
"front_second",
"inside_second",
"back_third",
"front_second",
"inside_third",
"back_fourth",
"front_second",
"inside_third"
);

So basically it looks at the three arrays, and whichever array has less values it will reuse the last value multiple times until it loops through the remaining keys in the longer arrays.

Is there a way to do this?

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
thindery
  • 1,164
  • 4
  • 23
  • 40
  • see: [array_merge](http://stackoverflow.com/questions/10034521/php-combine-arrays-into-one-big-array) – Austin Greco Jan 17 '13 at 14:26
  • You would use array_map() http://us2.php.net/manual/en/function.array-map.php – crush Jan 17 '13 at 14:31
  • You have forgotten to write where *exaclty* you got stumped, because from the description you give it's pretty clear that you know how to solve this. So your question is not clear. – hakre Jan 18 '13 at 09:27
  • E.g. post-fix the arrays with their last value ([`end`](http://php.net/end)) based on [`max`](http://php.net/max)imum [`count`](http://php.net/count), then re-order the array like in [PHP - how to flip the rows and columns of a 2D array](http://stackoverflow.com/q/2221476/367456). – hakre Jan 18 '13 at 09:37

3 Answers3

3
$front = array("front_first","front_second");
$inside = array("inside_first", "inside_second", "inside_third");
$back = array("back_first", "back_second", "back_third","back_fourth");

function foo() {
  $args = func_get_args();
  $max = max(array_map('sizeof', $args)); // credits to hakre ;)
  $result = array();

  for ($i = 0; $i < $max; $i += 1) {
    foreach ($args as $arg) {
      $result[] = isset($arg[$i]) ? $arg[$i] : end($arg); 
    }    
  }

  return $result;
}

$final = foo($back, $front, $inside);
print_r($final);

demo: http://codepad.viper-7.com/RFmGYW

Yoshi
  • 54,081
  • 14
  • 89
  • 103
  • Yep. Yours is 60% faster than mine below. – crush Jan 17 '13 at 15:00
  • I keep getting an error on the line where you set `$max` "Parse error: syntax error, unexpected T_FUNCTION, expecting ')'" – thindery Jan 17 '13 at 15:03
  • @thindery That's probably because you're using a php version which does not support [inline functions](http://php.net/manual/functions.anonymous.php). – Yoshi Jan 17 '13 at 15:22
2

Demo

http://codepad.viper-7.com/xpwGha

PHP

$front = array("front_first", "front_second");
$inside = array("inside_first", "inside_second", "inside_third");
$back = array("back_first", "back_second", "back_third", "back_fourth");

$combined = array_map("callback", $back, $front, $inside);

$lastf = "";
$lasti = "";
$lastb = "";

function callback($arrb, $arrf, $arri) {
    global $lastf, $lasti, $lastb;

    $lastf = isset($arrf) ? $arrf : $lastf;
    $lasti = isset($arri) ? $arri : $lasti;
    $lastb = isset($arrb) ? $arrb : $lastb;

    return array($lastb, $lastf, $lasti);
}

$final = array();

foreach ($combined as $k => $v) {
    $final = array_merge($final, $v);
}

print_r($final);

Output

Array
(
    [0] => back_first
    [1] => front_first
    [2] => inside_first
    [3] => back_second
    [4] => front_second
    [5] => inside_second
    [6] => back_third
    [7] => front_second
    [8] => inside_third
    [9] => back_fourth
    [10] => front_second
    [11] => inside_third
)
crush
  • 16,713
  • 9
  • 59
  • 100
0

Spreading the column data from multiple arrays with array_map() is an easy/convenient way to tranpose data. It will pass a full array of elements from the input arrays and maintain value position by assigning null values where elements were missing.

Within the custom callback, declare a static cache of the previously transposed row. Iterate the new transposed row of data and replace any null values with the previous rows respective element.

After transposing the data, call array_merge(...$the_transposed_data) to flatten the results.

Code: (Demo)

$front = ["front_first", "front_second"];
$inside = ["inside_first", "inside_second", "inside_third"];
$back = ["back_first", "back_second", "back_third", "back_fourth"];

var_export(
    array_merge(
        ...array_map(
            function(...$cols) {
                static $lastSet;
                foreach ($cols as $i => &$v) {
                    $v ??= $lastSet[$i];
                }
                $lastSet = $cols;
                return $cols;
            },
            $back,
            $front,
            $inside
        )
    )
);

Output:

array (
  0 => 'back_first',
  1 => 'front_first',
  2 => 'inside_first',
  3 => 'back_second',
  4 => 'front_second',
  5 => 'inside_second',
  6 => 'back_third',
  7 => 'front_second',
  8 => 'inside_third',
  9 => 'back_fourth',
  10 => 'front_second',
  11 => 'inside_third',
)
mickmackusa
  • 43,625
  • 12
  • 83
  • 136