2

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.

3 Answers 3

3

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

Sign up to request clarification or add additional context in comments.

1 Comment

A good answer. Not sure why the other upvoters missed this one.
1

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',
    ),
  ),
)

Comments

1

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;
            }
        }
    }

}

1 Comment

@mickmackusa Thanks for the heads up. Teach me to post untested code :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.