Search code examples
phparraysgroupingtransposechunks

Parse comma separated string, split array into chunks, then transpose


What is the best way to echo out an array where the values are grouped:

Array (
[0] => Service, Service, Service
[1] => 27 february, 2017, 27 march, 2017, 27 april, 2017
[2] => 08:00, 08:00, 08:00
)

If I want the result to be:

Service, 27 february, 2017 at 08:00.
Service, 27 march, 2017 at 08:00.
Service, 27 april, 2017 at 08:00.

This is what I have come up with so far:

<?php
$string = "Service, Service, Service, 8 mars, 2017, 22 mars, 2017, 5 april, 2017, 08:00, 08:00, 08:00";

$pattern = '/(\d+) (\w+), (\d+)/i'; //remove comma before year
$replacement = '${1} $2 $3';
$fixed = preg_replace($pattern, $replacement, $string);
 
$array = explode(', ', $fixed); 

$i=0;

foreach($array as $value) {
    echo $value.", ";
    $i++;

    if ($i == 3) {
        echo '<br>';
        $i = 0;
    }
}    
?>

The output:

Service, Service, Service, 
8 mars 2017, 22 mars 2017, 5 april 2017, 
08:00, 08:00, 08:00, 

So they are still in the wrong order... I just cant figure out how to sort the array and group the values I want one after another instead of in a row.


Solution

  • So long as the number of rows is known, it only takes:

    1. a regex to split the string on comma-spaces which immediately follow a one-or-more digits or a word starting with an uppercase letter,
    2. a call of array_chunk() and
    3. array_map() (with a null callback and data spreading) to "transpose" the data.

    Code: (Demo)

    $string = "Service, Service, Service, 8 mars, 2017, 22 mars, 2017, 5 april, 2017, 08:00, 08:00, 08:00";
    
    $rows = 3;
    
    var_export(
        array_map(
            null,
            ...array_chunk(
                preg_split('/(?:[A-Z][a-z]+|\d+)\K, /', $string),
                $rows
            )
        )
    );