Screaming Snake Case - FreeCodeCamp #140 Daily Challenge
Enunciado
Convertir un nombre de variable desde cualquiera de estos formatos:
- camelCase:
"thisIsVariable" - PascalCase:
"ThisIsVariable" - snake_case:
"this_is_variable" - kebab-case:
"this-is-variable"
A SCREAMING_SNAKE_CASE:
- Todas las letras en mayúsculas
- Palabras separadas por guiones bajos (
_)
Análisis Inicial
Objetivo
Identificar palabras individuales independientemente del formato original:
- Guiones:
-o_marcan límites de palabras - Mayúsculas: indican inicio de nueva palabra en camelCase/PascalCase
Luego unir con _ y convertir a mayúsculas.
Casos de Prueba
| Entrada | Salida | Formato |
|---|---|---|
"userEmail" | "USER_EMAIL" | camelCase |
"UserPassword" | "USER_PASSWORD" | PascalCase |
"user_id" | "USER_ID" | snake_case |
"user-address" | "USER_ADDRESS" | kebab-case |
"username" | "USERNAME" | palabra simple |
| strategia: Normalizar → Transformar |
flowchart TD
A["Input<br/>(cualquier formato)"] --> B["Normalizar a snake_case"]
B --> C["Split por '_'"]
C --> D["toUpperCase() cada palabra"]
D --> E["Join con '_'"]
E --> F["SCREAMING_SNAKE_CASE"]
style A fill:#e1f5ff
style F fill:#c8e6c9
Implementación
function toScreamingSnakeCase(variableName) {
// 1. Insertar _ antes de mayúsculas: "userEmail" → "user_Email"
const withUnderscores = variableName.replace(/([a-z])([A-Z])/g, '$1_$2')
// 2. Normalizar guiones: "user-address" → "user_address"
const normalized = withUnderscores.replace(/-/g, '_')
// 3. Dividir: "user_Email" → ["user", "Email"]
const words = normalized.split('_')
// 4. Mayúsculas + unir: ["user", "Email"] → "USER_EMAIL"
return words.map(word => word.toUpperCase()).join('_'
)
}Análisis de Complejidad
Temporal:
Cada operación recorre el string linealmente:
| Operación | Complejidad | Descripción |
|---|---|---|
replace (regex) | Examina cada carácter una vez | |
replace (guiones) | Recorre el string completo | |
split('_') | Divide el string | |
map().join() | Itera palabras y reconstruye |
Total:
Espacial:
Estructuras auxiliares creadas:
- Strings intermedios (
withUnderscores,normalized) - Array
wordscon palabras extraídas - String de salida
Todas proporcionales a la longitud del input O(n) donde n es la longitud del string de entrada.
La función realiza las siguientes operaciones lineales:
replace(/([a-z])([A-Z])/g, '$1_$2'): Recorre el string una vez para identificar transiciones de minúscula a mayúscula. En el peor caso, cada carácter se examina una vez.- **`replace(
✅ Manejados Correctamente
| Input | Output | Nota |
|---|---|---|
"" | "" | String vacío |
"username" | "USERNAME" | Palabra simple |
"aB" | "A_B" | Letras individuales |
"mixedFormat_case" | "MIXED_FORMAT_CASE" | Formatos combinados |
⚠️ Limitaciones
Acrónimos: "XMLParser" → "X_M_L_PARSER" (cada mayúscula genera separación)
Números: "user2Email" → "USER2EMAIL" (la regex actual no detecta números como límites)
**Guiones bajo
Conceptos Clave
- Regex con grupos de captura:
/([a-z])([A-Z])/g+'$1_$2'inserta caracteres entre grupos - Normalización de datos: Convertir múltiples formatos a uno intermedio reduce complejidad
- Pipeline funcional:
replace → split → map → joines declarativo y legible - Regex simple vs. compleja: Una sola regex que maneje todos los casos sería más difícil de mantener. La claridad prima sobre la brevedad.
Lo que Aprendí
✨ Normalizar primero simplifica el problema ✨ Las regex con $1, $2 permiten inserciones precisas ✨ split → map → join es un patrón común en transformaciones de textoos.