Padding a swift String for printing

前端 未结 6 660
迷失自我
迷失自我 2020-12-08 09:57

I\'m trying to print a list of Strings all padded to the same width.

In C, I would use something like printf(\"%40s\", cstr), where cstr is a C string.<

相关标签:
6条回答
  • 2020-12-08 09:58

    The following two functions return a string padded to the given width, either left or right justified. It is pure Swift 4, no NSString, and no C string either. You may choose if a string longer than the padding width will be truncated or not.

    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)
        }
    }
    
    0 讨论(0)
  • 2020-12-08 10:02

    For Swift >= 3

    line += string.padding(toLength: 40, withPad: " ", startingAt: 0)
    

    For Swift < 3

    NSString has the stringByPaddingToLength: method:

    line += string.stringByPaddingToLength(40, withString: " ", startingAtIndex: 0)
    
    0 讨论(0)
  • 2020-12-08 10:04
    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"
    
    0 讨论(0)
  • 2020-12-08 10:11

    Put all string-format-code into extension and reuse it wherever you want.

    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+++++++"
    
    0 讨论(0)
  • 2020-12-08 10:16

    Here's my solution, specific to String, but I'm sure someone smarter than I could make it more generic.

    extension String {
        func frontPadding(toLength length: Int, withPad pad: String, startingAt index: Int) -> String {
            return String(String(self.reversed()).padding(toLength: length, withPad: pad, startingAt: index).reversed())
        }
    }
    
    0 讨论(0)
  • 2020-12-08 10:18

    In Swift 3 you can use:

    let str = "Test string"
    let paddedStr = str.padding(toLength: 20, withPad: " ", startingAt: 0)
    

    Result string: "Test string "

    If you need to pad to the left the text (right justify), you can write the following function as an extension to 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))
            }
        }
    }
    

    So if you write:

    let str = "Test string"
    let paddedStr = str.leftPadding(toLength: 20, withPad: " ")
    

    Result string: " Test string"

    In Swift 4.1 the substring method is deprecated and there are a number of new methods to obtain a substring. Either prefix, suffix or subscripting the String with a Range<String.Index>.

    For the previous extension we can use the suffix method to accomplish the same result. Since the suffix method returns a String.SubSequence, it needs to be converted into a String before being returned.

    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))
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题