Cycle through array recursively PHP

I would like to create a function to cycle through simple array recursively

$values = [
    'sizes' => ['S', 'M', 'L', 'XL'],
    'colors' => ['Red', 'Blue', 'Green'],
    'types' => ['Short', 'Long'],
];

To get this result:
foreach($sizes as $size){
    foreach($colors as $color){
        foreach($types as $type){
            $str = "$size $color $type";
            // S Red Short
            // S Red Long
            // S Blue Short
            // ...
            // M Red Long
            // M Blue Short
            // M Blue Long
            // ...
            // XL Blue Long
            // XL Green Short
            // XL Green Long
        }
    }
}

My array is completely variable, I can have:
$values = [
    'sizes' => ['S', 'M'],
    'colors' => ['Red', 'Blue', 'Green', 'White', 'Black'],
];

Or
$values = [
    'sizes' => ['S', 'M', 'L'],
    'colors' => ['Red', 'Blue'],
    'type' => ['short']
];

Does anyone have a suggestion or an answer?
Thank in advance

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

A way to do this recursively is:

<?php

$properties = [
    'sizes'  => ['S', 'M', 'L', 'XL'],
    'colors' => ['Red', 'Blue', 'Green'],
    'types'  => ['Short', 'Long'],
];


function recurseProperties($properties, $output = '')
{
    // are there still values left in the properties array?
    if (count($properties) > 0) {
        // pick off first array from the properties
        $values = array_shift($properties);
        // do all values recursively
        foreach ($values as $value) {
            recurseProperties($properties, "$output $value");
        }
    } else {
        // output what we have so far
        echo trim($output) . PHP_EOL;
    }      
}

recurseProperties($properties);

The code is reasonably self-explanatory. I added some comments in the code. The output is:
 S Red Short
 S Red Long
 S Blue Short
 S Blue Long
 S Green Short
 S Green Long
 M Red Short
 M Red Long
 M Blue Short
 M Blue Long
 M Green Short
 M Green Long
 L Red Short
 L Red Long
 L Blue Short
 L Blue Long
 L Green Short
 L Green Long
 XL Red Short
 XL Red Long
 XL Blue Short
 XL Blue Long
 XL Green Short
 XL Green Long

Here is a PHP fiddle.

Method 2

You can use CrossJoin from Collection

    $values = [
    'sizes' => ['S', 'M', 'L', 'XL'],
    'colors' => ['Red', 'Blue', 'Green'],
    'types' => ['Short', 'Long'],
];

$valuesCollection = collect($values);

$collection = collect($valuesCollection->first());
$valuesCollection->shift();


$matrix = $collection
  ->crossJoin(...$valuesCollection->values())
  ->map(function($value){
    return implode(' ',array_values($value));
  });

dd($matrix);

Live Demo here

Method 3

If the number of elements are same in all array, you can use one for loop and just iterate all like, if number of elements are not same, you can take the largest one from them and assign empty string as default value in case element not present.

for($i = 0; $i < count($values['sizes']); $i++) {
   $size = $values['sizes'][$i] ?? "";
   $color = $values['colors'][$i] ?? "";
   $type = $values['types'][$i] ?? "";
   $str = $size . $color . $type;
}

This one option I can think of. may not work in all scenario, but based on the sample provided by you, I can think of this.I do not think you should use recursive for this. Recursive solution may eat your memory, so try to avoid that.

fiddle


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x