0

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!

1
  • I don't understand the logic. How can you call Array[0][0] -> Array[1][0] -> Array[2][0] if the base array have only two entries? key [2] would throw an undefined notice, wouldn't it? Commented Jan 28, 2015 at 17:18

3 Answers 3

1

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

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for the information. I'm analysing how I can apply it to what I need but I do appreciate the helpfull text and link. It has got a little clearer and with simple examples, such as fibonacci numbers, I understand it entirely. However, I'm still figuring this out. I will get it soon! Thanks for the help :D
Thanks for the information. But how can I affect the $item in the else ? All I have got is a string for $item and there is no way that I can affect it.
0

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

Comments

0

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.

6 Comments

The function returns this: ` array(5) { [0]=> string(16) "5" [1]=> string(16) "4" [2]=> string(16) "1" [3]=> string(16) "2" [4]=> string(16) "3" } ` It is going through each array and passing it to a final array but it does not join the values (ex: "5,1"). Nevertheless it is a great start for me to fiddle around with. Thanks!
What are the first and the second number corresponding to? Did you find a solution?
It's item characteristics IDs. Basically, I want to combine traits to certain items and generate a final product (ex: T-Shirt(Item) - Size XL, Color Blue(Traits)). I did not find a solution, yet. I'm having trouble joining them in unique strings. I did find a workaround (posted below), but this fails with more than 2 traits.
function recursive ($array, $total, $index, &$finalResult) { $totalAttributes = count($array[$index]); $subIndex = 0; for ($i = 0; $i < ($total/$totalAttributes); $i++) { foreach ($array[$index] as $row) { $finalResult[$index][$subIndex] = $row . ','; $subIndex++; } } if ($array[$index + 1] != NULL) { $this->recursive($array, $total, ++$index, $finalResult); } DO you have any idea?
I think I begin to understand what you want : you have a big array, which contains subarray. You want to 'multiply' each subarray with the other? Each key of the first subarray have all the values of the second subarray? Or am I going to far and I understand nothing? :P
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.