Ответ 1
NSString
имеет метод stringByPaddingToLength:
:
line += string.stringByPaddingToLength(40, withString: " ", startingAtIndex: 0)
Я пытаюсь распечатать список строк, заполненных одинаковой шириной.
В C я бы использовал нечто вроде printf("%40s", cstr),
, где cstr - строка C.
В Swift лучшее, что я мог придумать, это:
line += String(format: "%40s",string.cStringUsingEncoding(<someEncoding>))
Есть ли лучший способ?
NSString
имеет метод stringByPaddingToLength:
:
line += string.stringByPaddingToLength(40, withString: " ", startingAtIndex: 0)
В Swift 3 вы можете использовать:
let str = "Test string"
let paddedStr = str.padding(toLength: 20, withPad: " ", startingAt: 0)
Строка результата: "Test string "
Если вам нужно добавить слева текст (выровнять по правому краю), вы можете написать следующую функцию как расширение для 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))
}
}
}
Так что если вы напишите:
let str = "Test string"
let paddedStr = str.leftPadding(toLength: 20, withPad: " ")
Строка результата: " Test string"
В Swift 4.1 метод substring
устарел, и есть ряд новых методов для получения подстроки. prefix
, suffix
или подписка String
с Range<String.Index>
.
Для предыдущего расширения мы можем использовать метод suffix
для достижения того же результата. Поскольку suffix
метод возвращает String.SubSequence
, его необходимо преобразовать в String
прежде чем он будет возвращен.
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))
}
}
}
Поместите весь строковый формат в extension
и повторно используйте его там, где хотите.
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+++++++"
extension RangeReplaceableCollection where Self: StringProtocol {
func paddingToLeft(upTo length: Int, using element: Element = " ") -> SubSequence {
return repeatElement(element, count: Swift.max(0, length-count)) + suffix(Swift.max(count, count-length))
}
}
"123".paddingToLeft(upTo: 5) // " 123"
"123".paddingToLeft(upTo: 5, using: "0") // "00123"
"123".paddingToLeft(upTo: 3, using: "0") // "123"
"$199.99".dropLast(3).paddingToLeft(upTo: 10, using: "_") // "______$199"
Следующие две функции возвращают строку, дополненную до заданной ширины, с выравниванием по левому или правому краю. Это чистый Swift 4, ни строки NSString, ни строки Си. Вы можете выбрать, будет ли обрезана строка длиннее ширины отступа или нет.
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)
}
}