Length of String as extension of String

I know that there will be lots of pointers to duplicates but this worked before I updated to xcode 6.3 and now it has a problem with it.

The script:

  • Errors after updating to Xcode 8: “No such module” and “target overrides the `EMBEDDED_CONTENT_CONTAINS_SWIFT`build setting”
  • Add lefthand margin to UITextField
  • How to show a custom UIMenuItem for a UITableViewCell?
  • Core Data: does a fetch have to make a trip to persistent store?
  • Drawing a moving sine wave anti-aliased
  • How do I only allow access to my MySQL database from my iOS app? (Using webapp as gateway to db)
  • extension String {
    
        func removeCharsFromEnd(count:Int) -> String {
            var getSelf = self as String
            var stringLength = count(getSelf.utf16)
    
            let substringIndex = (stringLength < count) ? 0 : stringLength - count
    
            return self.substringToIndex(advance(self.startIndex, substringIndex))
        }
    }
    

    Error : Cannot invoke ‘count’ with an argument of list of type ‘(String.UTF16View)’


    I also want to point out that this new method for counting works everywhere else I have used out (outside of this extension).

    Thanks in advance.

    2 Solutions Collect From Internet About “Length of String as extension of String”

    count is the name of your extension method parameter and hides the
    Swift library function count(). You can rename the parameter
    or call

    var stringLength = Swift.count(getSelf.utf16)
    

    explicitly.

    But note that counting the number of UTF-16 code units is wrong here, it should be

    var stringLength = Swift.count(getSelf)
    

    to count the number of characters in the string, because that is what
    advance() also counts. You can verify that easily with

    let foo = "😀😁😂".removeCharsFromEnd(1)
    println(foo)
    

    Here is a simplified version of your method:

    extension String {
    
        func removeCharsFromEnd(count : Int) -> String {
            precondition(count >= 0, "Attempt to call removeCharsFromEnd() with a negative count")
            // Decrement `endIndex` by `count`, but not beyond `startIndex`:
            let idx = advance(self.endIndex, -count, self.startIndex)
            return self.substringToIndex(idx)
        }
    }
    

    using the three-argument version of advance() with a negative distance.

    Update for Swift 2/Xcode 7:

    extension String {
    
        func removeCharsFromEnd(count : Int) -> String {
            precondition(count >= 0, "Attempt to call removeCharsFromEnd() with a negative count")
            // Decrement `endIndex` by `count`, but not beyond `startIndex`:
            let idx = self.endIndex.advancedBy(-count, limit: self.startIndex)
            return self.substringToIndex(idx)
        }
    }
    
    var str = "Hello, playground"
    
    extension String {
        func removeCharsFromEnd(n:Int) -> String {
            return substringWithRange(Range(start: startIndex, end: advance(startIndex, count(self) < n ? 0 : count(self)-n )))
        }
    }
    
    "Hello, playground".removeCharsFromEnd(3)  // "Hello, playgro"
    "😀😁😂".removeCharsFromEnd(1)             // "😀😁"
    

    you can also use subscript:

    extension String {
        subscript(index: Int) -> String? {
            guard index >= 0 && index < characters.count else { return nil }
            return String(self[startIndex.advancedBy(index)])
        }
        subscript(range: Range<Int>) -> String? {
            guard
                range.startIndex >= 0 &&
                range.endIndex <= characters.count &&
                startIndex.advancedBy(range.endIndex) <= endIndex &&
                startIndex.advancedBy(range.startIndex) >= startIndex &&
                range.startIndex.distanceTo(range.endIndex) <= characters.count
            else { return nil }
            return self[startIndex.advancedBy(range.startIndex)..<startIndex.advancedBy(range.endIndex)]
        }
    }
    
    "Hello, playground"[0...4] // "Hello"
    "Hello, playground"[5]      // ","
    "Hello, playground"[7...16]  // "playground"
    
    "😀😁😂"[1]  // "😁"