The challenge
In this challenge, you will make a function that converts between camelCase
, snake_case
, and kebab-case
.
You must write a function that changes to a given case. It must be able to handle all three case types:
change_case("snakeCase", "snake") # "snake_case"
change_case("some-lisp-name", "camel") # "someLispName"
change_case("map_to_all", "kebab") # "map-to-all"
change_case("doHTMLRequest", "kebab") # "do-h-t-m-l-request"
change_case("invalid-inPut_bad", "kebab") # None
change_case("valid-input", "huh???") # None
change_case("", "camel") # ""
Your function must deal with invalid input as shown, though it will only be passed strings. Furthermore, all valid identifiers will be lowercase except when necessary, in other words on word boundaries in camelCase
.
The solution in Python code
Option 1:
import re
def change_case(label, target):
if ('_' in label) + ('-' in label) + (label != label.lower()) > 1:
return
if target == 'snake':
return re.sub('([A-Z])', r'_\1', label.replace('-', '_')).lower()
if target == 'kebab':
return re.sub('([A-Z])', r'-\1', label.replace('_', '-')).lower()
if target == 'camel':
return re.sub('([_-])([a-z])', lambda m: m.group(2).upper(), label)
Option 2:
def change_case(id, t):
q = ('_' in id) + ('-' in id) + any(x.isupper() for x in set(id))
if q > 1: return
d = {'kebab': '-', 'snake': '_'}
l, index = [''], 0
for x in id:
if not l[index] or not x.isupper() and x.isalpha() and l[index][-1].isalpha():
l[index] += x
elif x.isalpha():
l.append(x)
index += 1
else:
l.append('')
index += 1
if t in d:
return f'{d[t]}'.join(x.lower() for x in l)
if t == 'camel':
return ''.join(w.capitalize() if i else w for i,w in enumerate(l))
Option 3:
def change_case(id, t):
if '_' in id and '-' in id or t not in ['snake','camel','kebab']:return None
if not id: return ''
if not id.islower():
if '_' in id or '-' in id: return None
if '-' in id:
l=id.split('-')
elif '_' in id:
l=id.split('_')
else:
l,temp=[],''
for i in id:
if i.isupper():
l.append(temp)
temp=i.lower()
else:
temp+=i.lower()
l.append(temp)
if t=='snake':return '_'.join(l)
elif t=='kebab':return '-'.join(l)
else:return l[0][0]+''.join(i.capitalize() for i in l)[1:]
Test cases to validate our solution
test.it("Basic tests")
test.assert_equals(change_case("snakeCase", "snake"), "snake_case", "camelCase to snake_case conversion should work")
test.assert_equals(change_case("some-lisp-name", "camel"), "someLispName", "kebab-case to camelCase conversion should work")
test.assert_equals(change_case("map_to_all", "kebab"), "map-to-all", "snake_case to kebab-case conversion should work")
test.assert_equals(change_case("doHTMLRequest", "kebab"), "do-h-t-m-l-request", "camelCase to kebab-case conversion should work")
test.assert_equals(change_case("invalid-inPut_bad", "kebab"), None, "mIx-ed_cAse input should be considered invalid")
test.assert_equals(change_case("valid-input", "huh???"), None, "Invalid target cases should be dealt with")
test.assert_equals(change_case("", "camel"), "", "An empty string should not be changed.")