Note: I thought I could come up with a faster solution with a single regex, but I couldn't. Below is my failed method (you can learn from failure), and the results of a performance test, and my conclusion.
Efficiency can be measured many ways. If you wanted to reduce the number of functions called, then you could use a single regex and a function to handle the replacement.
([A-Z])|(\s)|([^a-z\d])
REY
The first group will have toLowerCase()
applied, the second will be replaced with a -
and the third will return nothing. I originally used +
quantifier for groups 1 and 3, but given the expected nature of the text, removing it result in faster execution. (thanks acheong87)
'Well Done!'.replace(/([A-Z])|(\s)|([^a-z\d])/g, function (match, $0, $1) {
if ($0) return String.fromCharCode($0.charCodeAt(0) + 32);
else if ($1) return '-';
return '';
});
jsFiddle
Performance
My method was the worst performing:
Acheong87 fastest
Original 16% slower
Mine 53% slower
jsPerf
Conclusion
Your method is the most efficient in terms of code development time, and the performance penalty versus acheong87's method is offset by code maintainability, readability, and complexity reduction. I would use your version unless speed was of the utmost importance.
The more optional matches I added to the regular expression, the greater the performance penalty. I can't think of any advantages to my method except for the function reduction, but that is offset by the if
statements and increase in complexity.