Nadav
Nadav

Reputation: 1819

Replace value in multidimensional php array

First, I have to say I already checked some answers but neither it wasn't exactly what I was looking for neither I couldn't fully understand the answer and how to use it.

I have this MultiDimensional array:

Array
(
    [field_5abcb693a68bc] => Array
        (
            [0] => Array
                (
                    [field_5abcbb1b51ddf] => mortgage
                    [field_5ae58a0b58b58] => 
                    [field_5abcbb1e51de0] => 10
                    [field_5abcbb2051de1] => הידגלה
                    [field_5abcbb2351de2] => 45,654,456
                    [field_5abcbb6251de3] => 
                    [field_5abcbb6651de4] => 04/2017
                    [field_5abcbb6851de5] => 4,454,656
                    [field_5abcbb6b51de6] => 24/07/2018
                    [field_5abcbbb351de7] => 657
                    [field_5abcbbb651de8] => 24/07/2018
                    [field_5abcbbb851de9] => 15
                    [field_5abcbbbb51dea] => yes
                )

        )

)  

And I want to find values that much the pattern of mm/yyyy. Regex is a good option, I know how to write the condition:

if ( preg_match('/^\d[1-9]\/[1-9][0-9][0-9][0-9]$/',$v) ) {
   //do stuff
}

I want to look in the inner part of the array for this pattern, and if it is a match, to change the value in the array to

$value = '01/' . $value;

means the value '04/2017' changes to '01/04/2017'.
note: there can be more than one value to change.
note: the name of the first array within the array [field_5abcb693a68bc] can vary and won't stay the same in other cases.
Thanks.

Upvotes: 2

Views: 395

Answers (3)

RiggsFolly
RiggsFolly

Reputation: 94682

You can anonymously process down the levels of the array without actually knowing any of the names of the keys like this for example

foreach ($arr as $key => &$outer) {
    foreach ($outer as &$inner) {
        foreach ($inner as $k => $v) {
            if ( preg_match('/^\d[1-9]\/[1-9][0-9][0-9][0-9]$/',$v) ) {
                $inner[$k] = '01/' . $v;
            }
        }
    }

}

Upvotes: 1

mickmackusa
mickmackusa

Reputation: 48069

You want to perform a conditional replacement using a regex pattern? preg_replace() seems sensible. preg_replace() is happy to iterate a one-dimensional array, so the lowest level can be directly served to it.

Notice that I've changed the pattern delimiter to avoid escaping the forward slash. I've also made the pattern more brief by using \d and the {3} quantifier. $0 means the "fullstring match". You don't have to write the unset() call to purge those temporary variables, but some developers consider it to be best practice because it avoids potential variable conflict down-script.

Code: (Demo)

$array = [
    'field_5abcb693a68bc' => [
        0 => [
            'field_5abcbb1b51ddf' => 'mortgage',
            'field_5ae58a0b58b58' => '',
            'field_5abcbb1e51de0' => '10',
            'field_5abcbb2051de1' => 'הידגלה',
            'field_5abcbb2351de2' => '45,654,456',
            'field_5abcbb6251de3' => '',
            'field_5abcbb6651de4' => '04/2017',
            'field_5abcbb6851de5' => '4,454,656',
            'field_5abcbb6b51de6' => '24/07/2018',
            'field_5abcbbb351de7' => '657',
            'field_5abcbbb651de8' => '24/07/2018',
            'field_5abcbbb851de9' => '15',
            'field_5abcbbbb51dea' => 'yes'
        ]
    ]
];

foreach ($array as &$set) {
    foreach ($set as &$subset) {
        $subset = preg_replace('~^\d[1-9]/[1-9]\d{3}$~', '01/$0', $subset);
    }
}
unset($set, $subset); // avoid future variable interferences
var_export($array);

Output:

array (
  'field_5abcb693a68bc' => 
  array (
    0 => 
    array (
      'field_5abcbb1b51ddf' => 'mortgage',
      'field_5ae58a0b58b58' => '',
      'field_5abcbb1e51de0' => '10',
      'field_5abcbb2051de1' => 'הידגלה',
      'field_5abcbb2351de2' => '45,654,456',
      'field_5abcbb6251de3' => '',
      'field_5abcbb6651de4' => '01/04/2017',
      'field_5abcbb6851de5' => '4,454,656',
      'field_5abcbb6b51de6' => '24/07/2018',
      'field_5abcbbb351de7' => '657',
      'field_5abcbbb651de8' => '24/07/2018',
      'field_5abcbbb851de9' => '15',
      'field_5abcbbbb51dea' => 'yes',
    ),
  ),
)

Upvotes: 1

Luke
Luke

Reputation: 2400

Use array_walk_recursive with reference to value as argument instead of regular value argument of callback.

It would work like that:

array_walk_recursive(
    $array,
    function (&$value) {
        if (preg_match('/^\d[1-9]\/[1-9][0-9][0-9][0-9]$/',$value)) {
            $value = '01/' . $value;
        }
    }
);

Check result on 3v4l.org

Upvotes: 3

Related Questions