🔍 ¿Por qué verificar la existencia de un elemento en un array Swift? ¿Y cómo hacerlo correctamente en 2025?
\n\nImagine: está escribiendo una aplicación para pedir pizza. El usuario seleccionó "Pepperoni", "Hawaiana" y "Margarita". Su código debe asegurarse de que "Pepperoni" ya esté en el carrito para no agregar un duplicado. O está trabajando con una base de datos de clientes y verifica si el correo electrónico está registrado en el sistema. Verificar la existencia de un elemento en un array es una de las operaciones más comunes en el desarrollo con Swift.
\n\nParecería sencillo, ¿verdad? Pero en 2025, cuando Swift evoluciona rápidamente y el rendimiento de las aplicaciones móviles es crítico, elegir el método incorrecto puede costarle retrasos en la interfaz de usuario u horas adicionales de depuración. En este artículo, analizaremos todas las formas de verificar un elemento en un array Swift: desde el simple contains() hasta closures avanzados y trabajo con tipos personalizados. Aprenderá qué método elegir para su tarea y por qué.
Por cierto, esta pregunta es una de las más populares en Stack Overflow (más de 200,000 visitas). Y le daremos una respuesta completa y moderna. ¡Vamos allá! 🚀
\n\n📦 Arrays en Swift: descripción básica (para los que tienen prisa)
\n\nUn array (Array) es una colección ordenada de elementos del mismo tipo. En Swift, los arrays son type-safe, lo que significa que no puede agregar accidentalmente una cadena a un array de números. Esto es tanto una ventaja (menos errores) como un desafío (debe especificar los tipos estrictamente).
let pizzaMenu: [String] = ["Margarita", "Pepperoni", "Hawaiana", "Cuatro quesos"]\nlet numbers: [Int] = [1, 2, 3, 4, 5]\n\n\nAhora pasemos a lo principal: ¿cómo verificar si un elemento está en el array?
\n\n🛠️ Top 5 métodos para verificar la existencia de un elemento en un array Swift
\n\n1. contains() — el rey de la simplicidad (Equatable)
\n\nLa forma más obvia y utilizada. El método contains(_:) devuelve true si se encuentra el elemento. Funciona solo con tipos que cumplen con el protocolo Equatable (y todos los tipos básicos lo hacen: String, Int, Double, etc.).
let pizzas = ["Margarita", "Pepperoni", "Hawaiana"]\nif pizzas.contains("Pepperoni") {\n print("¡Hay esa pizza!") // ✅ Imprimirá esto\n} else {\n print("Pizza no encontrada")\n}\n\n\nVentajas: legible, conciso, rápido.
\nDesventajas: no funciona si tiene un objeto complejo (estructura/clase) sin Equatable.
2. contains(where:) — para verificaciones complejas
\n\nSi necesita verificar no una coincidencia exacta, sino una condición (por ejemplo, "¿hay alguna pizza que cueste más de 500 rublos?"), use contains(where:). Acepta un closure que devuelve un Bool.
struct Pizza {\n let name: String\n let price: Int\n}\n\nlet order: [Pizza] = [\n Pizza(name: "Margarita", price: 450),\n Pizza(name: "Pepperoni", price: 550),\n Pizza(name: "Hawaiana", price: 500)\n]\n\nlet hasExpensivePizza = order.contains { $0.price > 500 }\nprint("¿Hay pizza cara? \\(hasExpensivePizza)") // true\n\n\nVentajas: flexibilidad, funciona con cualquier tipo.
\nDesventajas: un poco más lento que contains() (pero para el 99% de los casos la diferencia es imperceptible).
3. firstIndex(of:) — cuando el índice es importante
\n\nA veces no solo necesita saber si un elemento existe, sino también obtener su posición. Por ejemplo, para eliminarlo o reemplazarlo. El método firstIndex(of:) devuelve un Int? opcional.
let pizzas = ["Margarita", "Pepperoni", "Hawaiana"]\nif let index = pizzas.firstIndex(of: "Pepperoni") {\n print("Pepperoni está en la posición \\(index)") // 1\n} else {\n print("No encontrado")\n}\n\n\nImportante: firstIndex también requiere Equatable. Si su tipo no cumple con