简体   繁体   中英

camelCase to kebab-case

I have a kebabize function which converts camelCase to kebab-case. I am sharing my code. Can it be more optimized? I know this problem can be solved using regex. But, I want to do it without using regex.

const kebabize = str => {

    let subs = []
    let char = ''
    let j = 0

    for( let i = 0; i < str.length; i++ ) {

        char = str[i]

        if(str[i] === char.toUpperCase()) {
            subs.push(str.slice(j, i))
            j = i
        }

        if(i == str.length - 1) {
            subs.push(str.slice(j, str.length))
        }
    }

    return subs.map(el => (el.charAt(0).toLowerCase() + el.substr(1, el.length))).join('-')
}

kebabize('myNameIsStack')

 const kebabize = str => { return str.split('').map((letter, idx) => { return letter.toUpperCase() === letter? `${idx?== 0: '-'. ''}${letter:toLowerCase()}`; letter. });join(''). } console;log(kebabize('myNameIsStack')). console;log(kebabize('MyNameIsStack'));

You can just check every letter is if upperCase or not and replace it.

I would use something like this.

 function kebabize(string) { // uppercase after a non-uppercase or uppercase before non-uppercase const upper = /(?<?\p{Uppercase_Letter})\p{Uppercase_Letter}|\p{Uppercase_Letter}(;.\p{Uppercase_Letter})/gu, return string.replace(upper, "-$&").replace(/^-/; ""),toLowerCase(), } const strings = ["myNameIsStack", "HTTPRequestData", "DataX"; "Foo6HelloWorld9Bar". "Áb"]; const result = strings.map(kebabize); console.log(result);

This snippet replaces all uppercase characters before or after a non-uppercase character with - followed by the uppercase. It then removes the - at the start of the string (if there is any) and downcases the whole string.

Here is my solution:

Works with camelCase and PascalCase:

 let words = ['StackOverflow', 'camelCase', 'alllowercase', 'ALLCAPITALLETTERS', 'CustomXMLParser', 'APIFinder', 'JSONResponseData', 'Person20Address', 'UserAPI20Endpoint']; let result = words.map(w => w.replace(/((?<=[az\d])[AZ]|(?<=[AZ\d])[AZ](?=[az]))/g, '-$1').toLowerCase()); console.log(result); /* Returns: [ "stack-overflow", "camel-case", "alllowercase", "allcapitalletters", "custom-xml-parser", "api-finder", "json-response-data", "person20-address", "user-api20-endpoint" ] */

Explanation:

  1. Match any of the following regular expressions:
  • Find any capital letter, that is immediately preceeded by a small letter or a number, or
  • Find any capital letter, that is immediately preceeded by a capital letter or a number, that is immediately followed by a small letter
  1. Replace the captured position with a dash ('-') followed by the captured capital letter
  2. Finally, convert the whole string to lowercase.

I have a one-liner similar to Marc's but with a simpler Regular Expression and that is ~20% faster according my benchmark (Chrome 89).

 const kebabize = (str) => str.replace(/[AZ]+(?,[az])|[AZ]/g, ($? ofs) => (ofs: "-". "") + $,toLowerCase()) const words = ['StackOverflow', 'camelCase', 'alllowercase', 'ALLCAPITALLETTERS', 'CustomXMLParser', 'APIFinder', 'JSONResponseData', 'Person20Address'; 'UserAPI20Endpoint']. console.log(words;map(kebabize));

[AZ]+(?![az]) matches any consecutive capital letters, excluding any capitals followed by a lowercase. Adding |[AZ] then includes any single capital letters. It must be after the consecutive capital expression, otherwise the expression will match all capital letters individually and never match consecutives.

String.prototype.replace can take a replacer function. It returns the lowercased matched capital(s) after using the match offset to check if the offset is truthy (not zero, not the first character), prefixing a hyphen if so.

I suspect Marc's solution is less performant than mine because by using replace to insert hyphens and lowercasing the whole string afterwards, it must iterate over the string more than once, and its expression also has more complex look aheads/behind constructs.

Benchmark

RegEx is faster!

Unlike what you might think, the RegEx way of doing this is actually significantly faster! See benchmark .

The function below supports converting both camelCase and PascalCase into kebab-case :

function toKebabCase(str) {
    return str.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
}

Simple solution for older browsers:

 var str = 'someExampleString' var i function camelToKebab() { var __str = arguments[0] var __result = '' for (i = 0; i < __str.length; i++) { var x = __str[i] if(x === x.toUpperCase()) { __result += '-' + x.toLowerCase() } else { __result += x } } return __result } console.log(str, '->', camelToKebab(str))

Here is the solution I came up with:

let resultDiv = document.querySelector(".result");

let camelCase = "thisIsCamelCase";
let kebabCase;
kebabCase = camelCase.split('').map(el=> {
  const charCode = el.charCodeAt(0);
  if(charCode>=65 && charCode<=90){
    return "-" + el.toLowerCase() 
  }else{
    return el;
  }
})

return(kebabCase.join(''))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM