Actually I needed a function which converts underscore to camel-case. But then I've had the idea: Why not extend the function so, that is works the other way around?
Finally I recalled that there is a third case which programmers use: Pascal-Case. So I included that too.
The function doesn't work perfect but as long as the different cases are used as expected it works alright.
Any hints and suggestions concerning improvements are welcomed.
/**
* Converts a string to either underscore-case or camel-case or
* to pascal-case.
* @param {string} toChange
* @param {string} [toCase='toUnderscoreCase'] - Options:
* 'toUnderscoreCase' | 'toCamelCase' | 'toPascalCase'
* @returns {string} according toCase-param.
* Returns an empty string in case of error.
*/
function changeCase(toChange, toCase) {
var needle = null;
var funct = null;
var needleChangingUpperLower = /[a-z0-9]_[a-z0-9]/g;
var needleToUnderscore = /(([a-zA-Z0-9]*?)(([a-z0-9][A-Z]))|([a-zA-Z0-9]*)$)/g;
toCase = toCase || 'toUnderscoreCase'
if ( !toChange ||
typeof toChange !== 'string' ||
toChange.length < 2 ) {
return '';
}
if (toChange.search(/[^\w]/g) > -1) {
return '';
}
function toChangingUpperLower(match) {
var chars = match.split('_');
return chars[0] + chars[1].toUpperCase();
}
function toUnderscore(match, wordComplete, wordTruncated, wordChange) {
var ret = '';
if (wordChange) {
var chars = wordChange.split('');
ret += wordTruncated.toLowerCase() + chars[0] + '_' + chars[1].toLowerCase();
} else {
ret = wordComplete.toLowerCase();
}
return ret;
}
switch (toCase) {
case 'toCamelCase':
needle = needleChangingUpperLower;
toChange = toChange.slice(0, 1).toLowerCase() + toChange.slice(1);
funct = toChangingUpperLower;
break;
case 'toPascalCase':
needle = needleChangingUpperLower;
toChange = toChange.slice(0, 1).toUpperCase() + toChange.slice(1);
funct = toChangingUpperLower;
break;
case 'toUnderscoreCase':
needle = needleToUnderscore;
funct = toUnderscore;
break;
default:
return '';
}
return toChange.replace(needle, funct);
}
// --- Usage-examples and test-cases --------
var tests = [ {
toChange: 'get_amount_of_taxes',
toCase: ''
},
{
toChange: 'ThisIsTheSoCalledPascalCase',
toCase: 'toCamelCase'
},
{
toChange: 'thisIsTheSoCalledCamelCase',
toCase: 'toPascalCase'
},
{
toChange: 'set_sum_of_articles',
toCase: 'toCamelCase'
},
{
toChange: 'getAmountOfTaxes',
toCase: 'toUnderscoreCase'
},
{
toChange: 'XMLHttpRequest',
toCase: 'toUnderscoreCase'
},
{
toChange: 'theXMLconnector1ForABC',
toCase: 'toUnderscoreCase'
},
{
toChange: 'aB',
toCase: 'toUnderscoreCase'
},
{
toChange: 'c',
toCase: 'toUnderscoreCase'
},
{
toChange: [2, 3],
toCase: 'toUnderscoreCase'
},
{
toChange: 'abc#123Spec',
toCase: 'toUnderscoreCase'
},
{
toChange: 'abc_890-spec',
toCase: 'toCamelCase'
},
{
toChange: 'get_amount_of_taxes',
toCase: 'abc123'
} ];
tests.forEach(function(test) {
var result = changeCase(test.toChange, test.toCase);
var log = console.log;
var err = console.error;
!result
? err( '%s\n%s',
'Something has gone wrong.',
JSON.stringify(test, null, 2))
: log( '%s - %s',
result,
JSON.stringify(test, null, 2));
});