1

s is a native Swift string consisted of ASCII characters only. It could be arbitrary long. What's the most efficient way to figure out if s is short than a certain length (say, 100k)?

if countElements(s) < 100_000 is not the most efficient, as countElements is O(n) complexity and s could have billions of characters.

Ethan
  • 18,584
  • 15
  • 51
  • 72

2 Answers2

2

If you're sure you don't need to worry about anything other than ASCII, you can use the utf16Count property (which is the length property of the bridged NSString):

let stringLength = superLongString.utf16Count

If you want to be able to handle Unicode you need to walk the string, you just don't want to walk the whole string. Here's a function to count just up to your limit:

func lengthLessThanMax(#string: String, maximum max: Int) -> Bool {
    var idx = string.startIndex
    var count = 0
    while idx < string.endIndex && count < max {
        ++count
        idx = idx.successor()
    }
    return count < max
}

lengthLessThanMax(string: "Hello!", maximum: 10)
// true
lengthLessThanMax(string: "Hello! Nice to meet you!", maximum: 10)
// false
Nate Cook
  • 92,417
  • 32
  • 217
  • 178
  • Are you sure getting the `length` of an `NSString` backed by a Swift `String` is O(1) not O(n)? What about `-utf16Count` for a Swift string? How that bridging works under the hood? – Ethan Nov 03 '14 at 03:11
  • Yes - the `length` property on `NSString` returns the number of Unicode characters, while in Swift, each element of a `String` can be made up of multiple Unicode characters. It's that second part that is hard and makes Swift strings not easily countable (i.e., you need to traverse the string to know how many characters it has). Ole Begemann has a [great post on Swift strings](http://oleb.net/blog/2014/07/swift-strings/) that goes into the details more. – Nate Cook Nov 03 '14 at 03:17
  • @Ethan Forgot about `.utf16Count` - that's actually added by Foundation; it's the same as using the length of the bridged NSString. – Nate Cook Nov 03 '14 at 03:20
-1

just chose what your want:

var emoji = ""
countElements(emoji)              //returns 1
emoji.utf16Count                  //returns 2
emoji.bridgeToObjectiveC().length //returns 2

find from Get the length of a String

Community
  • 1
  • 1
Tinyfool
  • 1,460
  • 2
  • 18
  • 40