Get nth character of a string in Swift programming language

后端 未结 30 1953
一整个雨季
一整个雨季 2020-11-22 01:26

How can I get the nth character of a string? I tried bracket([]) accessor with no luck.

var string = \"Hello, world!\"

var firstChar = string[         


        
相关标签:
30条回答
  • 2020-11-22 01:56

    In Swift 5 without extension to the String :

    var str = "ABCDEFGH"
    for char in str {
    if(char == "C") { }
    }
    

    Above Swift code as same as that Java code :

    int n = 8;
    var str = "ABCDEFGH"
    for (int i=0; i<n; i++) {
    if (str.charAt(i) == 'C') { }
    }
    
    0 讨论(0)
  • 2020-11-22 01:57

    Swift 5.2

    let str = "abcdef"
    str[1 ..< 3] // returns "bc"
    str[5] // returns "f"
    str[80] // returns ""
    str.substring(fromIndex: 3) // returns "def"
    str.substring(toIndex: str.length - 2) // returns "abcd"
    

    You will need to add this String extension to your project (it's fully tested):

    extension String {
    
        var length: Int {
            return count
        }
    
        subscript (i: Int) -> String {
            return self[i ..< i + 1]
        }
    
        func substring(fromIndex: Int) -> String {
            return self[min(fromIndex, length) ..< length]
        }
    
        func substring(toIndex: Int) -> String {
            return self[0 ..< max(0, toIndex)]
        }
    
        subscript (r: Range<Int>) -> String {
            let range = Range(uncheckedBounds: (lower: max(0, min(length, r.lowerBound)),
                                                upper: min(length, max(0, r.upperBound))))
            let start = index(startIndex, offsetBy: range.lowerBound)
            let end = index(start, offsetBy: range.upperBound - range.lowerBound)
            return String(self[start ..< end])
        }
    }
    

    Even though Swift always had out of the box solution to this problem (without String extension, which I provided below), I still would strongly recommend using the extension. Why? Because it saved me tens of hours of painful migration from early versions of Swift, where String's syntax was changing almost every release, but all I needed to do was to update the extension's implementation as opposed to refactoring the entire project. Make your choice.

    let str = "Hello, world!"
    let index = str.index(str.startIndex, offsetBy: 4)
    str[index] // returns Character 'o'
    
    let endIndex = str.index(str.endIndex, offsetBy:-2)
    str[index ..< endIndex] // returns String "o, worl"
    
    String(str.suffix(from: index)) // returns String "o, world!"
    String(str.prefix(upTo: index)) // returns String "Hell"
    
    0 讨论(0)
  • 2020-11-22 01:57

    I just had the same issue. Simply do this:

    var aString: String = "test"
    var aChar:unichar = (aString as NSString).characterAtIndex(0)
    
    0 讨论(0)
  • 2020-11-22 01:57

    Swift's String type does not provide a characterAtIndex method because there are several ways a Unicode string could be encoded. Are you going with UTF8, UTF16, or something else?

    You can access the CodeUnit collections by retrieving the String.utf8 and String.utf16 properties. You can also access the UnicodeScalar collection by retrieving the String.unicodeScalars property.

    In the spirit of NSString's implementation, I'm returning a unichar type.

    extension String
    {
        func characterAtIndex(index:Int) -> unichar
        {
            return self.utf16[index]
        }
    
        // Allows us to use String[index] notation
        subscript(index:Int) -> unichar
        {
            return characterAtIndex(index)
        }
    }
    
    let text = "Hello Swift!"
    let firstChar = text[0]
    
    0 讨论(0)
  • 2020-11-22 01:58

    Xcode 11 • Swift 5.1

    You can extend StringProtocol to make the subscript available also to the substrings:

    extension StringProtocol {
        subscript(_ offset: Int)                     -> Element     { self[index(startIndex, offsetBy: offset)] }
        subscript(_ range: Range<Int>)               -> SubSequence { prefix(range.lowerBound+range.count).suffix(range.count) }
        subscript(_ range: ClosedRange<Int>)         -> SubSequence { prefix(range.lowerBound+range.count).suffix(range.count) }
        subscript(_ range: PartialRangeThrough<Int>) -> SubSequence { prefix(range.upperBound.advanced(by: 1)) }
        subscript(_ range: PartialRangeUpTo<Int>)    -> SubSequence { prefix(range.upperBound) }
        subscript(_ range: PartialRangeFrom<Int>)    -> SubSequence { suffix(Swift.max(0, count-range.lowerBound)) }
    }
    

    extension LosslessStringConvertible {
        var string: String { .init(self) }
    }
    

    extension BidirectionalCollection {
        subscript(safe offset: Int) -> Element? {
            guard !isEmpty, let i = index(startIndex, offsetBy: offset, limitedBy: index(before: endIndex)) else { return nil }
            return self[i]
        }
    }
    

    Testing

    let test = "Hello USA                                                                     
    0 讨论(0)
  • 2020-11-22 01:58

    Swift 3: another solution (tested in playground)

    extension String {
        func substr(_ start:Int, length:Int=0) -> String? {
            guard start > -1 else {
                return nil
            }
    
            let count = self.characters.count - 1
    
            guard start <= count else {
                return nil
            }
    
            let startOffset = max(0, start)
            let endOffset = length > 0 ? min(count, startOffset + length - 1) : count
    
            return self[self.index(self.startIndex, offsetBy: startOffset)...self.index(self.startIndex, offsetBy: endOffset)]
        }
    }
    

    Usage:

    let txt = "12345"
    
    txt.substr(-1) //nil
    txt.substr(0) //"12345"
    txt.substr(0, length: 0) //"12345"
    txt.substr(1) //"2345"
    txt.substr(2) //"345"
    txt.substr(3) //"45"
    txt.substr(4) //"5"
    txt.substr(6) //nil
    txt.substr(0, length: 1) //"1"
    txt.substr(1, length: 1) //"2"
    txt.substr(2, length: 1) //"3"
    txt.substr(3, length: 1) //"4"
    txt.substr(3, length: 2) //"45"
    txt.substr(3, length: 3) //"45"
    txt.substr(4, length: 1) //"5"
    txt.substr(4, length: 2) //"5"
    txt.substr(5, length: 1) //nil
    txt.substr(5, length: -1) //nil
    txt.substr(-1, length: -1) //nil
    
    0 讨论(0)
提交回复
热议问题