Convert array of mixed-case words into sanitized snakecase values

5.9k views Asked by At

I have an array and filtering the values with the array_filter() function. I used echo on the filter function to see if the filtered value is working or not.

$columns = array(
    0 => 'ISO',
    1 => 'Country',
    2 => 'Country Code',
    3 => 'Type of number',
    4 => 'Voice Enabled',
    5 => 'SMS Enabled',
    6 => 'MMS Enabled',
    7 => 'Domestic Voice Only',
    8 => 'Domestic SMS only',
    9 => 'Price /num/month',
    10 => 'Inbound Voice price/min',
    11 =>  'Inbound SMS price/msg ',
    12 =>  'Inbound MMS price/msg ',
    13 => 'Beta Status',
    14 => 'Address Required',
);
        
echo '<pre>';
$columns = array_filter($columns, '_filter_column_names');
echo '</pre>';

function _filter_column_names($column_name){
    $column_name = str_replace(' /', '_', $column_name);
    $column_name = strtolower(str_replace(array(' ', '/'), '_', trim($column_name)));

    echo $column_name.'<br>';
    return $column_name;
}

echo '<pre>';
    print_r($columns);
echo '</pre>';

Result

iso
country
country_code
type_of_number
voice_enabled
sms_enabled
mms_enabled
domestic_voice_only
domestic_sms_only
price_num_month
inbound_voice_price_min
inbound_sms_price_msg
inbound_mms_price_msg
beta_status
address_required

Array
(
    [0] => ISO
    [1] => Country
    [2] => Country Code
    [3] => Type of number
    [4] => Voice Enabled
    [5] => SMS Enabled
    [6] => MMS Enabled
    [7] => Domestic Voice Only
    [8] => Domestic SMS only
    [9] => Price /num/month
    [10] => Inbound Voice price/min
    [11] => Inbound SMS price/msg 
    [12] => Inbound MMS price/msg 
    [13] => Beta Status
    [14] => Address Required
)

The changes performed in the function body are not retained when printing the array. Although it seems the array values inside the filter function is filtering correctly.

You can also see it live here http://3v4l.org/SttJ3

3

There are 3 answers

0
Hamatti On BEST ANSWER

I think you have misunderstood what array_filter does. As the docs say, it "Filters elements of an array using a callback function" which means the callback should return true/false depending on if it should be included or not.

What you probably meant to use, is array_map which runs callback on every item and returns modified items back.

0
anubhava On

You are not using callback properly, as per PHP official manual:

Iterates over each value in the array passing them to the callback function. If the callback function returns true, the current value from array is returned into the result array.

Your callback needs to return FALSE for the elements you don't want in output array.

0
mickmackusa On

Completely abandon the use of array_filter(), it is the wrong tool for the task.

Convert all values to lowercase, then replace all sequences of non-letters to underscores.

Code: (Demo)

var_export(
    preg_replace(
        '/[^a-z]+/',
        '_',
        array_map('strtolower', $columns)
    )
);