swift - Relleno de una cadena veloz para imprimir
string padding (5)
En Swift 3 puedes usar:
let str = "Test string"
let paddedStr = str.padding(toLength: 20, withPad: " ", startingAt: 0)
Cadena de resultados: "Test string "
Si necesita rellenar el texto a la izquierda (justificación a la derecha), puede escribir la siguiente función como una extensión de String
:
extension String {
func leftPadding(toLength: Int, withPad character: Character) -> String {
let newLength = self.characters.count
if newLength < toLength {
return String(repeatElement(character, count: toLength - newLength)) + self
} else {
return self.substring(from: index(self.startIndex, offsetBy: newLength - toLength))
}
}
}
Así que si escribes:
let str = "Test string"
let paddedStr = str.leftPadding(toLength: 20, withPad: " ")
Cadena de resultados: " Test string"
En Swift 4.1, el método de substring
está en desuso y hay varios métodos nuevos para obtener una subcadena. Ya sea prefix
, suffix
o subíndices de la String
con un Range<String.Index>
.
Para la extensión anterior podemos usar el método del suffix
para lograr el mismo resultado. Dado que el método del suffix
devuelve un String.SubSequence
, debe convertirse en un String
antes de ser devuelto.
extension String {
func leftPadding(toLength: Int, withPad character: Character) -> String {
let stringLength = self.count
if stringLength < toLength {
return String(repeatElement(character, count: toLength - stringLength)) + self
} else {
return String(self.suffix(toLength))
}
}
}
Estoy intentando imprimir una lista de Cadenas todas rellenadas al mismo ancho.
En C, usaría algo como printf("%40s", cstr),
donde cstr es una cadena en C.
En Swift, lo mejor que pude encontrar es esto:
line += String(format: "%40s",string.cStringUsingEncoding(<someEncoding>))
¿Hay alguna manera mejor?
Las dos funciones siguientes devuelven una cadena rellenada al ancho dado, ya sea a la izquierda o a la derecha. Es puro Swift 4, no NSString, y tampoco C string. Puede elegir si una cadena más larga que el ancho de relleno se truncará o no.
extension String {
func rightJustified(width: Int, truncate: Bool = false) -> String {
guard width > count else {
return truncate ? String(suffix(width)) : self
}
return String(repeating: " ", count: width - count) + self
}
func leftJustified(width: Int, truncate: Bool = false) -> String {
guard width > count else {
return truncate ? String(prefix(width)) : self
}
return self + String(repeating: " ", count: width - count)
}
}
Ponga en extension
código de formato de cadena y reutilícelo donde desee.
extension String {
func padding(length: Int) -> String {
return self.stringByPaddingToLength(length, withString: " ", startingAtIndex: 0)
}
func padding(length: Int, paddingString: String) -> String {
return self.stringByPaddingToLength(length, withString: paddingString, startingAtIndex: 0)
}
}
var str = "str"
print(str.padding(10)) // "str "
print(str.padding(10, paddingString: "+")) // "str+++++++"
NSString
tiene el método stringByPaddingToLength:
:
line += string.stringByPaddingToLength(40, withString: " ", startingAtIndex: 0)
extension StringProtocol {
func paddingToLeft(upTo length: Int, using element: Element) -> String {
return String(repeatElement(element, count: Swift.max(0, length-count))) + suffix(Swift.max(count, count-length))
}
}
"123".paddingToLeft(upTo: 5, using: "0") // "00123"
"123".paddingToLeft(upTo: 3, using: "0") // "123"