Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift: String starts(with:) vs hasPrefix

String.hasPrefix (or [NSString hasPrefix]) was always part of Foundation. However, I just noticed that now we also have starts(with:).

This method comes from Sequence but it also works for String.

My question is, which one should I prefer? Are there any performance considerations? I'm used to hasPrefix from Objective-C days, but starts(with:) is more intuitive and works for other sequences.

like image 570
noamtm Avatar asked Feb 21 '19 12:02

noamtm


People also ask

What is hasPrefix in Swift?

Returns a Boolean value that indicates whether a given string matches the beginning characters of the receiver.

How do I check if a string starts with Swift?

Swift provide a in-built function named starts() to check whether the string starts with the specified string or not. If the given string starts with specified string, then it will return true. Otherwise, it will return false.

How do you add a prefix to a string in Swift?

URL. init(string: imageURLString, relativeTo: URL. init(string:"http://")) seems to do the trick. Well write your own extension that does exactly that.

What is prefix and suffix in Swift?

Checking what a String starts with and ends with You can use the hasPrefix(_:) and hasSuffix(_:) methods to test equality with another String. let str = "Hello, playground" if str.hasPrefix("Hello") { // true print("Prefix exists") } if str.hasSuffix("ground") { // true print("Suffix exists") }


1 Answers

String.hasPrefix() is implemented in StringLegacy.swift as

extension String {

  public func hasPrefix(_ prefix: String) -> Bool {
    if _fastPath(self._guts.isNFCFastUTF8 && prefix._guts.isNFCFastUTF8) {
      guard prefix._guts.count <= self._guts.count else { return false }
      return prefix._guts.withFastUTF8 { nfcPrefix in
        let prefixEnd = nfcPrefix.count
        return self._guts.withFastUTF8(range: 0..<prefixEnd) { nfcSlicedSelf in
          return _binaryCompare(nfcSlicedSelf, nfcPrefix) == 0
        }
      }
    }

    return starts(with: prefix)
  }

}

which means (if I understand it correctly): If both the string and the prefix candidate use a UTF-8 based storage then the UTF-8 bytes are compared directly. Otherwise it falls back to starts(with:) and does a Character based comparison.

So there is no difference in the result, but hasPrefix() is optimized for native Swift strings.

Note: This is the from the master (Swift 5) branch, the situation might be different in earlier versions.

like image 96
Martin R Avatar answered Sep 28 '22 06:09

Martin R