1

I am working on a script that processes data that is submitted from a third party web service that I don't control. I need to clean up some of the user-submitted data. Specifically, I need to go through each array and reformat all of the first names and last names to be sure they are properly capitalized (Ernest Hemingway instead of ERnest HEMINGWAY).

I have been using ucwords(strtolower()) to fix the capitalization, but I need to apply that method to all of the values stored in the first_name and last_name keys in each array. There are other strings that I don't want to change, only the first_name and last_name values. Here's an example of the array:

Array 
(
    [authors] => Array
            (
                [0] => Array
                    (
                        [first_name] => Ernest
                        [last_name] => HEMINGWAY
                        [book] => Too many to mention, but I like the Sun Also Rises 
                [1] => Array
                    (
                        [first_name] => john
                        [last_name] => steinbeck
                        [book] => East of Eden
    )

    [actors] => Array
            (
                [0] => Array
                    (
                        [first_name] => jOhn
                        [last_name] => WAYNE
                        [occupation] => Just generally a bad dude. 
                [1] => Array
                    (
                        [first_name] => clint
                        [last_name] => eastwood
                        [occupation] => Go ahead. Make my day. 
    )
)

Any thoughts on how I can loop through each array and apply ucwords(strtolower()) to only the first_name and last_name values? There are a lot of arrays that need this, so I am hoping to be able to programatically find and format the first_name and last_name values. The array format needs to be the same post-processing, with only the values changed.

EDIT: I am sure that, as suggested below, array_walk_recursive is the way to go. I wasn't able to get it to work, but I did create a new method that does the job. Here it is for reference:

protected function _fixCase(array $data)
{
    $newData = $data; 
    foreach  ($newData as $key => $value) {
        switch (true) {
            case stristr($key, 'first_name') || stristr($key, 'last_name'); 
                $newData[$key] = ucwords(strtolower($value)); 
                break; 
            default: 
                ''; 
        }
    }
    return $newData;
}
2
  • you may want to have a look at array_walk_recursive. The second parameter you get in the callback function will be the key, so just check if that one is equal to first_name or last_name before you apply you cleanup. php.net/manual/en/function.array-walk-recursive.php Commented May 10, 2016 at 22:14
  • Keep in mind that not all names will be properly capitalized this way. Commented May 10, 2016 at 22:16

1 Answer 1

2

Recursively walk the array with a callback:

array_walk_recursive($array, function(&$item, $key) {
        if ($key === 'first_name' || $key === 'last_name') {
            $item = ucwords(strtolower($item));
        }
    }
);

This will alter the items in place (&$item) if the $key matches what you want to change.

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

2 Comments

That makes my comment somewhat redundant... Something with minds and great and alike ;)
Thanks for the information. I wasn't able to get array_walk_recursive to work, but I'm sure that's due to my own limitations. I ended up creating a function that is probably less elegant, but gets the job done.

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.