string - texto - Cómo reemplazar el enésimo carácter de una cadena por otra
reemplazar una cadena por otra en c (10)
¿Cómo podría reemplazar el enésimo carácter de una String
con otra?
func replace(myString:String, index:Int, newCharac:Character) -> String {
// Write correct code here
return modifiedString
}
Por ejemplo, replace("House", 2, "r")
debe ser igual a "Horse"
.
Aquí hay una respuesta eficiente:
import Foundation
func replace(myString:String, index:Int, newCharac:Character) -> String {
return myString.substringToIndex(index-1) + newCharac + myString.substringFromIndex(index)
}
Creo que lo que @Greg estaba tratando de lograr con su extensión es esto:
mutating func replace(characterAt index: Int, with newChar: Character) {
var chars = Array(characters)
if index >= 0 && index < self.characters.count {
chars[index] = newChar
let modifiedString = String(chars)
self = modifiedString
} else {
print("can''t replace character, its'' index out of range!")
}
}
uso:
let source = "House"
source.replace(characterAt: 2, with: "r") //gives you "Horse"
Después de mirar los Swift Docs, logré hacer esta función:
//Main function
func replace(myString:String, index:Int, newCharac:Character) -> String {
//Looping through the characters in myString
var i = 0
for character in myString {
//Checking to see if the index of the character is the one we''re looking for
if i == index {
//Found it! Now instead of adding it, add newCharac!
modifiedString += newCharac
} else {
modifiedString += character
}
i = i + 1
}
// Write correct code here
return modifiedString
}
Tenga en cuenta que esto no se ha probado, pero debería darle la idea correcta.
En Swift 4 es mucho más fácil.
let newString = oldString.prefix(n) + char + oldString.dropFirst(n + 1)
Esto es un ejemplo:
let oldString = "Hello, playground"
let newString = oldString.prefix(4) + "0" + oldString.dropFirst(5)
donde el resultado es
Hell0, playground
El tipo de newString
es Substring. Tanto prefix
como dropFirst
devuelven la Substring
. La subcadena es un segmento de una cadena; en otras palabras, las subcadenas son rápidas porque no necesita asignar memoria para el contenido de la cadena, pero se usa el mismo espacio de almacenamiento que la cadena original.
He ampliado la respuesta de Nate Cooks y la he transformado en una extensión de cadena.
extension String {
//Enables replacement of the character at a specified position within a string
func replace(_ index: Int, _ newChar: Character) -> String {
var chars = Array(characters)
chars[index] = newChar
let modifiedString = String(chars)
return modifiedString
}
}
uso:
let source = "House"
let result = source.replace(2,"r")
el resultado es "caballo"
He encontrado esta solución.
var string = "Cars"
let index = string.index(string.startIndex, offsetBy: 2)
string.replaceSubrange(index...index, with: "t")
print(string)
// Cats
Las cadenas en swift no tienen un descriptor de acceso para leer o escribir un solo carácter. Hay una excelente publicación en el blog por Ole Begemann que describe cómo funcionan las cadenas en Swift.
Nota: la implementación a continuación es incorrecta, lea el apéndice
Así que la forma correcta es llevar la parte izquierda de la cadena hasta el carácter del index -1
, agregar el carácter de reemplazo y luego agregar la cadena desde el índice + 1 hasta el final:
func myReplace(myString:String, index:Int, newCharac:Character) -> String {
var modifiedString: String
let len = countElements(myString)
if (index < len) && (index >= 0) {
modifiedString = myString.substringToIndex(index) + newCharac + myString.substringFromIndex(index + 1)
} else {
modifiedString = myString
}
return modifiedString
}
Nota: en mi implementación, elegí devolver la cadena original si el índice no está en un rango válido
Addendum Gracias a @slazyk, que descubrió que mi implementación es incorrecta (ver comentario), estoy proporcionando una nueva versión única y rápida de la función.
func replace(myString:String, index:Int, newCharac:Character) -> String {
var modifiedString: String
if (index < 0) || (index >= countElements(myString)) {
modifiedString = myString
} else {
var start = myString.startIndex
var end = advance(start, index)
modifiedString = myString[start ..< end]
modifiedString += newCharac
start = end.successor()
end = myString.endIndex
modifiedString += myString[start ... end]
}
return modifiedString
}
La respuesta de @Codester se ve muy bien, y es probablemente lo que yo usaría. Sin embargo, sería interesante saber cómo se comparan los rendimientos, utilizando una solución totalmente rápida y, en cambio, un puente hacia el objetivo-c.
Las soluciones que usan métodos de NSString
fallarán para cualquier cadena con caracteres Unicode de múltiples bytes. Aquí hay dos formas nativas de Swift para abordar el problema:
Puede utilizar el hecho de que una String
es una secuencia de Character
para convertir la cadena en una matriz, modificarla y convertirla de nuevo:
func replace(myString: String, _ index: Int, _ newChar: Character) -> String {
var chars = Array(myString) // gets an array of characters
chars[index] = newChar
let modifiedString = String(chars)
return modifiedString
}
replace("House", 2, "r")
// Horse
Alternativamente, puedes atravesar la cuerda tú mismo:
func replace(myString: String, _ index: Int, _ newChar: Character) -> String {
var modifiedString = String()
for (i, char) in myString.characters.enumerate() {
modifiedString += String((i == index) ? newChar : char)
}
return modifiedString
}
Dado que estos se mantienen completamente dentro de Swift, ambos son seguros para Unicode:
replace("🏠🏡🏠🏡🏠", 2, "🐴")
// 🏠🏡🐴🏡🏠
Por favor vea la respuesta de NateCook para más detalles.
func replace(myString: String, _ index: Int, _ newChar: Character) -> String {
var chars = Array(myString.characters) // gets an array of characters
chars[index] = newChar
let modifiedString = String(chars)
return modifiedString
}
replace("House", 2, "r")
Esto ya no es válido y en desuso.
Siempre puede usar swift String
con NSString
. Así que puede llamar a la función NSString
en swift String
. Por el viejo stringByReplacingCharactersInRange:
puedes hacerlo así
var st :String = "House"
let abc = st.bridgeToObjectiveC().stringByReplacingCharactersInRange(NSMakeRange(2,1), withString:"r") //Will give Horse
func replace(myString:String, index:Int, newCharac:Character) -> String {
var modifiedString = myString
let range = Range<String.Index>(
start: advance(myString.startIndex, index),
end: advance(myString.startIndex, index + 1))
modifiedString.replaceRange(range, with: "/(newCharac)")
return modifiedString
}
Sin embargo, preferiría pasar una String
que un Character
.