Search code examples
phpmultidimensional-arraymapreducepreg-matcharray-column

Use array_column in combination with preg_match


Lets suppose we have an array of arrays that needs to be converted to rows

From this:

Array
(
    [subject] => Array
        (
            [0] => EDN:LOC:DERR
            [1] => EDN:LOC:DOXX
            [2] => EDN:LOC:NTTT
            [3] => EDN:LOC:NAGA
        )

    [object] => Array
        (
            [0] => ABS:D01::ADFPAZ01
            [1] => ABS:D01::DOXYWITX
            [2] => ABS:D01::NAGBAAD2
            [3] => ABS:D01::NAGGAAD2
        )

    [units] => Array
        (
            [0] => ABS:D06::UNAA
            [1] => ABS:D06::UMMM
            [2] => ABS:D06::UPOP
            [3] => ABS:D06::UPOP
        )

To this:

[0] => "'DERR' , 'ADFPAZ01' , 'UNAA'"
[1] => "'DOXX' , 'DOXYWITX' , 'UMMM'"
[2] => "'NTTT' , 'NAGBAAD2' , 'UPOP'"
[3] => "'NAGA' , 'NAGGAAD2' , 'UPOP'"

So I need the arrays to be cleaned by a pattern and compressed into lines.

I managed the compact view with the following function

$array_res = array();

for ($i=0; $i<=$totalEntries-1; $i++) {
   array_push($array_res, implode("', '", array_column($array_of_arrays, $i)));
}

My regex pattern is $pattern = '([^.:]*$)'; And it collects a sequence of letters from the end of the string until it finds a colon. And I used preg_match($pattern, $string, $match) to receive the proper string into the $match variable.

However, I cannot combine the above two procedures either with array_filter or array_map inside the for loop.

EDIT: Note that there can be a subarray that contains values without a colon. In that case we have to get the value as is

[units] => Array
    (
         [0] => NULL
         [1] => VALUE1
         [2] => VALUE2
         [3] => NULL
    )

Solution

  • Rather than using a regex, this just uses array_walk() to process the extracted column and for each item it uses strrchr() with : as the last character to match (although it will include the :, so uses substr() to remove the first char)...

    for ($i=0; $i<=$totalEntries-1; $i++) {
        $newRow = array_column($array_of_arrays, $i);
        array_walk($newRow, function (&$data) { 
            $data = substr(strrchr(":".$data, ":") , 1);
        });
        $array_res[] = "'".implode("', '", $newRow)."'";
    }
    

    The part ":".$data deals with the time when there is no : in the string, it will always ensure that it does find something to use.