I have from 3 to 10 arrays containing 20 to 50 value each.
I want to merge them into a single, flat, indexed array, but not the way array_merge
works.
I rather want to take the 1st value of the 1st array, then the 1st value of the second array, then the 1st value of the third array and so on.
Keys are not an issue here, It could be numerical or associative array, I'm just keeping the values, not the original keys.
Values in real application can be mixed so merging and sorting afterwards is not an option.
So if I had 3 arrays like so:
$array1 = array('1-1', '1-2', '1-3');
$array2 = array('2-1', '2-2', '2-3', '2-4');
$array3 = array('3-1', '3-2');
I would need the result to be an array containing the value in this order:
1-1, 2-1, 3-1, 1-2, 2-2, 3-2, 1-3, 2-3, 2-4
So far I have this piece of code :
$array = array($array1, $array2, $array3);
$newarray = array();
foreach ($array as $a) {
$v = array_shift($a);
if (isset($v)) {
$newarray[] = $v;
}
}
print_r($newarray);
but, of course, it only runs the 1st set of value and give me:
Array ( [0] => 1-1 [1] => 2-1 [2] => 3-1 )
array_shift
is what I need here because it remove the value from the old array (I don't need it anymore) and I move it to the new array (if it isset
). see: http://php.net/manual/en/function.array-shift.php
I'm pretty sure I will need a function and loop it until all arrays are empty, but I just can't wrap my head around this one. Any help will be greatly appreciated. Or even better if someone knows a native php function that does that.
Here's a simple one-liner...
$arr1 = ['1-1', '1-2', '1-3'];
$arr2 = ['2-1', '2-2', '2-3', '2-4'];
$arr3 = ['3-1', '3-2'];
$result = array_filter(call_user_func_array(array_merge, array_map(null, $arr1, $arr2, $arr3)));
So, maybe not so simple... Some explanation.
array_map(null, ...);
makes use of the feature of array_map
explained in example 4 of the PHP docs but without any transformation to the values (hence, null).
So, this will give you:
array(4) {
[0]=>
array(3) {
[0]=>
string(3) "1-1"
[1]=>
string(3) "2-1"
[2]=>
string(3) "3-1"
}
[1]=>
array(3) {
[0]=>
string(3) "1-2"
[1]=>
string(3) "2-2"
[2]=>
string(3) "3-2"
}
[2]=>
array(3) {
[0]=>
string(3) "1-3"
[1]=>
string(3) "2-3"
[2]=>
NULL
}
[3]=>
array(3) {
[0]=>
NULL
[1]=>
string(3) "2-4"
[2]=>
NULL
}
}
Then, we need to "flatten" the array, concatenating all the sub-arrays together.
This is achieved using array_merge
, but that doesn't take an array, so we use call_user_func_array
to feed the array into it's arguments.
Then the array_filter
to remove the nulls (introduced by array_map
due to the original arguments not being the same length).