Search code examples
phparraysgrouping

Split a flat array into a 2d array by starting a new subarray when an empty element is encountered


I am looking for something similar to array_chunk() but using an empty value as the separator.

I have:

Array
(
    [0] => /some/path:
    [1] => file.csv
    [2] => file.dat
    [3] => 
    [4] => /some/other/path:
    [5] => file.csv
    [6] => file.csv.gz
    [7] => file.dat
    [8] => 
    [9] => /some/other/other/path:
    [10] => file.csv
    [11] => file.dat
)

And would like to achieve -

Array
(
    [0] => Array
        (
            [0] => /some/path:
            [1] => file.csv
            [2] => file.dat
        )

    [1] => Array
        (
            [0] => /some/other/path:
            [1] => file.csv
            [2] => file.csv.gz
            [3] => file.dat
        )

    [2] => Array
        (
            [0] => /some/other/other/path:
            [1] => file.csv
            [2] => file.dat
        )
)

Note, I can't just chunk on every 3 as you can see some locations will have more than 1 file.

I can achieve via loop and counter, but I am hoping there is a cleaner method?


Solution

  • Best way I can think of is this loop which I think is pretty clean:

    /**
     * @param array  $inputArr  The array you wish to split.
     * @param string $splitStr  The string you wish to split by.
     *
     * @return array
     */
    function split_arrays($inputArr, $splitStr) {
        $outputArr = array();
        $i         = 0;
        foreach ($inputArr as $data) {
            if ($data == $splitStr) {
                $i++;
                continue;
            }
            $outputArr[$i][] = $data;
        }
        return $outputArr;
    }
    

    The other way I thought of also uses loops but is not as clean. It searches for the index of the next split string and breaks off that chunk.

    /**
     * @param array  $inputArr  The array you wish to split.
     * @param string $splitStr  The string you wish to split by.
     *
     * @return array
     */
    function split_arrays2($inputArr,$splitStr) {
        $outputArr = array(); $i=0;
        while(count($inputArr)) {
            $index = array_search($splitStr,$inputArr)
            if($index === false) $index = count($inputArr);
            $outputArr[$i++] = array_slice($inputArr,0,$index);
            $inputArr = array_slice($inputArr,$index+1);
        }
        return $outputArr;
    }
    

    If and only if you are using a string for the split string which is not ever going to show up inside the middle of the other strings (space may or may not be the case for this) then I agree with the others that implode and explode are much simpler. In your case:

    /**
     * @param array  $inputArr  The array you wish to split.
     * @param string $splitStr  The string you wish to split by.
     *
     * @return array
     */
    function split_arrays3($inputArr,$splitStr) {
        $outputArr = array(); $i=0;
        $str = implode("|",$inputArr);
        $arr = explode("|$splitStr|");
        foreach($arr as $i=>$string)
            $outputArr[$i] = explode("|",$string);
        return $outputArr;
    }