Tengo una matriz de nombres que se parece a la siguiente. ["John Doe", "Blog de María"]
Lo que quiero hacer es procesar esta matriz y devolver una matriz con las iniciales como las siguientes.
["JD", "MB"]
Ya lo hice, pero mi código es feo e ineficiente (bucles anidados). Probablemente esté bien para una matriz pequeña como en mi ejemplo.
¿Cómo puedo procesar mi matriz de manera más eficiente?
let contacts = ["John Doe", "Mary Blog"] var initalsArray: [String] = [] let names = contacts.map {$0} for name in names { var initals: String = "" let fullname = name.components(separatedBy: " ") for part in fullname { if part.count > 0 { initals += part[0] } } initalsArray.append(initals) }Debe procesar todos los elementos de la matriz.
Para cada elemento, debe detectar los espacios y recuperar la siguiente letra.
Luego debe construir la matriz de salida con mayúsculas concatenadas.
Así que realmente no veo cómo podrías evitar un doble bucle.
Solo if part.count > 0 es innecesario.
Alternativamente, puede escanear las cadenas usted mismo para evitar generar el nombre completo de la matriz fullname .
Probablemente también pueda obtener el resultado mediante el procesamiento de expresiones regulares, pero esto sería un mazo para romper nueces. no
Una posible implementación del bucle interior. (Lo siento si esto no es válido, no conozco a Swift).
var space: Bool = true for c in name { if space && c != ' ' { initials+= c } space= c == ' ' } Tenga en cuenta que la condición adicional (opcional) c != ' ' protege contra espacios dobles.
Puede usar el mapa para eliminar algunos de sus propios bucles
let contacts = ["John Doe", "Mary Blog"] let result = contacts.map { $0.components(separatedBy: .whitespacesAndNewlines).map { String($0.prefix(1)) }.joined(separator: "") } print(result)No sé si esto es más rápido, tal vez le dé a Apple la oportunidad de optimizar algo que es difícil de hacer.
No comparé la eficiencia de esto con las respuestas anteriores, pero si está tratando con names , usar PersonNameComponentsFormatter lo ayudará mucho. Consulta la documentación aquí .
En su caso, el siguiente código da el resultado requerido.
let formatter = PersonNameComponentsFormatter() let contacts = ["John Doe", "Mary Blog"] var initalsArray: [String] = [] for contact in contacts { if let name = formatter.personNameComponents(from: contact) { formatter.style = .abbreviated initalsArray.append(formatter.string(from: name)) } } output -> ["JD", "MB"]
En realidad, esta respuesta, aunque similar, puede ser un poco más rápida.
let contacts = ["John Doe", "Mary Blog"] let result = contacts.map { $0.components(separatedBy: .whitespacesAndNewlines).reduce("") { $0 + String($1.prefix(1)) } } print(result)En lugar de construir matrices internas y luego unirlas, simplemente las agregué a la cadena de primeras letras anteriores