Interview Question Walkthrough — converting kebab-case to camel case

A recent interview question compelled me to dive deeper into converting input designs into different outputs. I’ve come across several instances throughout projects requiring a string or kebab-case input (usually coming from an API) to transform into camelcase format in order to sync properly with an applications’ functionality. Thus, I thought it would be helpful to walk through a basic strategy that can make converting any case a little less complicated.

Basic case formats look like:

camelCase
kebab-case
snake_case
PascalCase

To go about this, the first step would simply be to convert any string to camel case. One that will accept both snake and kebab cases. Note — this does not include strings that have spaces; for ex: you cannot pass a string such as “this string” and expect the output to be “thisString.” This is possible, but for our purposes, we are focusing on kebab and snake cases.

const changeToCamel = (s) => {
return s.replace(/[-_][a-z])/i, ($1) => {
return $1.toUpperCase()
.replace('-','')
.replace('_','')
})};

Although this seems like a lot, it is actually quite simple. Starting with the replace method in Javascript which returns a modified string where the pattern is replaced, for example:

let string1 = "String replace!";
let string2 = string1.replace(/replace/i, "Replaced");
// string2 will output: "String Replaced!"

Back to our original example (changeToCamel), we are searching for either a dash (-) or an underscore ( _ ), followed by a letter ranging from a-z (line 2 in code example). The i that follows the expression tells us to ignore case — this way we can match kebab-case or kebab-Case, converting both to one output of kebabCase. However, if you require to treat both of these inputs differently, you can remove the i that follows the expression.

You will also notice that we wrapped our search action and the following letter range in parenthesis: ([-_][a-z]) - grouping them into a matching group $1. For example, if our input is “this_input”, the variable $1 would read ‘ _i ’. After this, we can simply use the given Javascript function ‘ toUpperCase() ’ to convert the matching segment of our string input to uppercase. The following line(s) then remove the dash or underscore completing our output.

Now that we know how to convert a single case of snake or kebab case input to camel case we can look at nested object keys. This is often the format provided to us when using APIs instead of single strings.

Let’s test an example that consists of both snake and kebab case:

let test = {
person_name: {
first_name: [ 'mark' ],
last_name: [ 'khan' ]
},
person-gender: [
{ 'female-gender': true },
{ 'male-gender': false }
],
};

Although we’d instantly think to loop over the object keys provided in this example and convert them to camel case using the function we’ve prepared, our function doesn’t deal with nested object inputs. We would need nothing more flexible and recursive. Our method needs to be able to deliver whether the values of the object are a list or any other data type.

In order to do this, we first need to figure out exactly what we’re dealing with; is it an array, object, etc. This can be slightly difficult to obtain because in Javascript almost everything is an object. Due to this, we have to sort of work backwards. First, let’s find out if our input is an array by using:

const isArray = function(a) {
return Array.isArray(a)
};

Next, we need to test if it’s really an object — making sure it is not null, not an array and not a function (Javascript will return all of these types as an Object).

So:

const isRealObject = function(o) {
return o === Object(o) && !isArray(o) && typeof o !== 'function'
};

Now that we know what our input is, we can go ahead and write out our function to convert object keys to camel case:

const givenKeysToCamel = function(o) {
if (isRealObject(o)) {
let n = {};
Object.keys(o).forEach((k) => n[changeToCamel(k)] = givenKeysToCamel(o[k]) )}
return n;
} else if (isArray(o)) {
return o.map((i) => {
return givenKeysToCamel(i)
)}}
return o;
};

In summary: we are accepting an object into our function. We test to see if it’s an object using our initial method (isRealObject). If yes, we loop through the keys of the object and convert them to camel case. In our next case, we test to see if the input is an array. If yes, we loop through the array and recursively call our givenKeysToCamel function. Lastly, if both cases fail — meaning that we are not dealing with either an object or an array, we simply return the initial input.

NOTE: this will not alter the cases of the actual list items coming back from the API. Our function will only apply to the key of an object item. Happy coding!

References: https://www.w3schools.com/js/js_regexp.asp#:~:text=In%20JavaScript%2C%20regular%20expressions%20are,where%20the%20pattern%20is%20replaced.

--

--

Software engineer navigating through problems in Rails and React. I like sharing my thinking processes, solutions and project learnings. I’m based in LI, NY.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Saman Batool

Software engineer navigating through problems in Rails and React. I like sharing my thinking processes, solutions and project learnings. I’m based in LI, NY.