Reputation: 3
I have a multidimensional array with these values:
array(2) {
[0]=>
array(2) {
[0]=>
string(16) "5"
[1]=>
string(16) "4"
}
[1]=>
array(3) {
[0]=>
string(16) "1"
[1]=>
string(16) "2"
[2]=>
string(16) "3"
}
}
For now the contents of the arrays are only int, but more complex values can be passed through brackets.
However, the number of "sub-arrays" I can varies and can be as small as 1 and large as PHP can handle it.
I wish to loop through the first value of the first array, then the first value of the second array, then the first value of the third array, etc.
Array[0][0] -> Array[1][0] -> Array[2][0]
Array[0][0] -> Array[1][0] -> Array[2][1]
Array[0][0] -> Array[1][1] -> Array[2][0]
Array[0][0] -> Array[1][1] -> Array[2][1]
Array[0][0] -> Array[1][2] -> Array[2][0]
Array[0][0] -> Array[1][2] -> Array[2][1]
Array[0][1] -> Array[1][0] -> Array[2][0]
Array[0][1] -> Array[1][0] -> Array[2][1]
Array[0][1] -> Array[1][1] -> Array[2][0]
Array[0][1] -> Array[1][1] -> Array[2][1]
Array[0][1] -> Array[1][2] -> Array[2][0]
Array[0][1] -> Array[1][2] -> Array[2][1]
// Example with 2 values in each array.
I've been told that a recursive function would do the trick but I have no experience with them and so far I only manage to get partial results.
This is my current code
// $array - Multidimensional array above
// $ini - Current array - ex: $array[0]
// $ini - Number of main arrays left - ex: count($array)
// $result - string that houses the temporary value
// $finalResult - Array that combines all the string when there is nothing left
function r ($array, $ini, $int, $result, $finalResult)
{
for ($i = 0; $i < count($array[$ini]); $i++)
{
$result = $array[$ini][$i] . ',' . $result;
if ($int != 0)
{
$result = $this->r($array, ++$ini, --$int, $result, $finalResult);
}
else
{
$finalResult[] = $result;
}
}
return $finalResult;
}
This is what I get from it
array(2) {
[0]=>
string(22) "2,Array"
[1]=>
string(39) "3,2,Array"
}
// I managed at some point get the values separate but, sadly
The desired outcome of the function is that the values be displayed in this matter:
array(2) {
[0]=>
string(16) "5, 1"
[0]=>
string(16) "5, 2"
[0]=>
string(16) "5, 3"
[0]=>
string(16) "4, 1"
[0]=>
string(16) "4, 2"
[0]=>
string(16) "4, 3"
}
Any guidance in the right direction would be greatly appreciated.
Thanks in advance!
Upvotes: 0
Views: 9739
Reputation: 46
Maybe I'm too late but I believe this is what you're asking, No recursion needed but still quite a memory hog i'm afraid!
function array_combine_subarray_values( array $groupArray ){
// boost available memory
//ini_set('memory_limit', '512M');
//count the elements in each subarray index
$lenArrs = [];
foreach ($groupArray as $arr) {
$lenArrs[] = count($arr);
}
// total number of distinct cases
$m = array_product($lenArrs);
// save our arrays' lengths
$lenArrskeep=$lenArrs;
$repArr = [];
// find the number of sequential repetitions for a given index of the subarrays
foreach ($lenArrs as $lenKey => $len) {
$repetitions = 1;
unset($lenArrs[$lenKey]);
foreach ($lenArrs as $lenMultiplierKey => $lenMultiplier) {
$repetitions *= $lenMultiplier;
}
$repArr[$lenKey] = $repetitions;
}
$target=[];
// iterate through all possible cases
for ($i =0;$i<$m;$i++){
//fill each combination/case
foreach ($repArr as $index => $repetitions) {
$target[$i][]=$groupArray[$index][($i/$repetitions)%$lenArrskeep[$index]];
}
}
return $target;
}
$groupArr = [
[0, 3, 6],
[1, 4 ,7],
[2, 5, 8]
];
//result
0 1 2
#1 0 1 2
#2 0 1 5
#3 0 1 8
#4 0 4 2
#5 0 4 5
#6 0 4 8
#7 0 7 2
#8 0 7 5
#9 0 7 8
#10 3 1 2
#11 3 1 5
#12 3 1 8
#13 3 4 2
#14 3 4 5
#15 3 4 8
#16 3 7 2
#17 3 7 5
#18 3 7 8
#19 6 1 2
#20 6 1 5
#21 6 1 8
#22 6 4 2
#23 6 4 5
#24 6 4 8
#25 6 7 2
#26 6 7 5
#27 6 7 8
Upvotes: 0
Reputation: 338
I made quickly a function that you can try, tell me if it fits your wish.
function recursive ($array, &$final)
{
$length = count($array);
for ($i = 0; $i < $length; $i++)
{
if (is_array($array[$i]))
recursive($array[$i], $final);
else
$final[] = $array[$i];
}
}
$array
is the array you want to transform, and $final
is the result of the transformation when passed by reference.
Upvotes: 0
Reputation: 6956
This is the basic idea of recursion:
$data = array(/* multi-dimensional */);
$result = iterate($data);
function iterate(array $array)
{
$result = array();
foreach($array as $item) {
if(is_array($item)) {
$result[] = iterate($item);
} else {
$changed = $item; // do something to the value.
$result[] = $changed;
}
}
return $result;
}
For each node in the array you check if it itself can be iterated, and so you call the same function again from within itself and return the value each time.
If it cannot be iterated, then the node is a target, which should be read, changed, deleted or ignored.
There is a more advanced implementation for array iteration which is part of the Iterator
interface family, the one that applies to you would be RecursiveArrayIterator
.
http://www.php.net//manual/en/class.recursivearrayiterator.php
Upvotes: 1