«Ceros» perdidos: ¿por qué Int no almacena ceros a la izquierda y cómo vivir con ello?
\n\n¿Alguna vez has intentado mostrar en pantalla el número 007 y solo obtenías 7? ¿Te resulta familiar? Bienvenido al club de desarrolladores en Swift que, tarde o temprano, se enfrentan a la pregunta: «¿Cómo agregar ceros a la izquierda a un Int?».
Esta pregunta en Stack Overflow ha acumulado miles de visitas, y no es de extrañar. Parece una tarea simple: mostrar un número de pedido como «001234» en lugar de «1234», o mostrar la hora como «09:05» en lugar de «9:5». Pero Swift, al ser un lenguaje fuertemente tipado, separa el concepto de «número» y su «representación en cadena». Int es una entidad matemática. Para él, 007 es simplemente 7. Los ceros a la izquierda se pierden durante la inicialización.
En este artículo, analizaremos todos los enfoques principales para resolver este problema. Aprenderás cómo formatear correctamente números enteros, qué método elegir para diferentes tareas y cómo no caer en una trampa de rendimiento. Recorreremos el camino desde simples máscaras de cadena hasta el potente NumberFormatter de Foundation. ¡Allá vamos!
¿Por qué Int no puede almacenar «001»? Breve explicación
\n\nAntes de sumergirnos en el código, entendamos la naturaleza del fenómeno. Int en Swift es un número entero con signo de 64 bits (o 32 bits en dispositivos antiguos). Su representación interna es código binario. Un cero a la izquierda no tiene significado matemático.
let number = 007 // ¿Error? ¡No!\nprint(number) // Imprime: 7\n\nEl compilador de Swift ni siquiera te permitirá escribir 007 en el código (a menos que sea un literal en sistema octal, pero ahí el prefijo es 0o). Conclusión: los ceros a la izquierda son un problema de formateo, no de almacenamiento de datos. Resolvemos la tarea a nivel de presentación (UI, registro, exportación).
Método n.º 1: El clásico — String(format:)
\n\nLa respuesta más popular en Stack Overflow es usar la función String(format:), heredada de Objective-C (a través del puente con NSString). Es una forma rápida y concisa.
Ejemplo: agregar 3 ceros a la izquierda
\n\nlet number = 7\nlet formatted = String(format: "%04d", number)\nprint(formatted) // "0007"\n\nEl especificador %04d significa:
- \n
%— inicio del especificador; \n 0— rellenar posiciones vacías con ceros, no con espacios; \n 4— ancho mínimo del campo (4 caracteres); \n d— número entero decimal (Int). \n
Si el número es más largo de 4 caracteres (por ejemplo, 12345), el formateo no lo truncará; obtendrás «12345».
\n\nVentajas y desventajas
\n- \n
- Ventajas: Simple, rápido, una sola línea. Funciona en todas las versiones de Swift. \n
- Desventajas: Usa
NSStringinternamente, lo que puede ser un poco más lento que una solución pura de Swift. Hay que recordar la sintaxis de formateo estilo C. No está localizado (no considera separadores de miles si se necesitan). \n
Cuándo usarlo: Para casos simples: registros, depuración, salida de ID, cuando no se necesita localización.
\n\nMétodo n.º 2: Swift puro — String(repeating:count:) + sufijo
\n\nSi quieres evitar el puente con Objective-C y escribir en Swift «puro», puedes hacerlo manualmente. Es un excelente ejercicio para entender las cadenas.
\n\nextension Int {\n func leadingZeros(_ totalDigits: Int) -> String {\n let stringValue = String(self)\n let zerosCount = max(0, totalDigits - stringValue.count)\n return String(repeating: "0", count: zerosCount) + stringValue\n }\n}\n\nlet number = 42\nprint(number.leadingZeros(5)) // "00042"\n\n¿Cómo funciona?
\n- \n
- Convertimos el Int en una cadena. \n
- Calculamos cuántos ceros agregar:
totalDigits - length. Si