NSString.contains(_:) returns false for empty string argument

Six weeks ago there was a discussion [1] (and a subsequent fix [2]) about the behavior of `String.hasPrefix(_:)` and `String.hasSuffix(_:)` with empty string arguments. After the fix, `str.hasPrefix("")` always returns `true`.

This leads to inconsistent behavior with the `NSString.contains(_:)` method, which returns `false` for an empty string argument:

    let str = "Hello"
    str.contains("") // returns false

If `contains` were part of the stdlib like `hasPrefix` and `hasSuffix` are, I would consider this a bug. But `contains` comes from Foundation and I'm not sure how that changes things. Would it make sense to add a variant of `contains(_:)` to the stdlib and fix the behavior there?

I'm assuming it's too late for Swift 3 and it will be fixed with the String remodeling in Swift 4 anyway, but I just noticed this and I thought I'd ask.

Ole

[1]: [swift-evolution] Change Request: Make myString.hasPrefix("") and myString.hasSuffix("") return true
[2]: [SR-2131] The empty string is not a prefix/suffix of itself (or any string) · Issue #44739 · apple/swift · GitHub

Six weeks ago there was a discussion [1] (and a subsequent fix [2])
about the behavior of `String.hasPrefix(_:)` and
`String.hasSuffix(_:)` with empty string arguments. After the fix,
`str.hasPrefix("")` always returns `true`.

This leads to inconsistent behavior with the `NSString.contains(_:)`
method, which returns `false` for an empty string argument:

    let str = "Hello"
    str.contains("") // returns false

If `contains` were part of the stdlib like `hasPrefix` and `hasSuffix`
are, I would consider this a bug. But `contains` comes from Foundation
and I'm not sure how that changes things. Would it make sense to add a
variant of `contains(_:)` to the stdlib and fix the behavior there?

It might be worth doing something for Swift 3.1

I'm assuming it's too late for Swift 3 and it will be fixed with the
String remodeling in Swift 4 anyway,

That's my plan.

···

on Mon Sep 05 2016, Ole Begemann <swift-evolution@swift.org> wrote:

but I just noticed this and I thought I'd ask.

Ole

[1]: [swift-evolution] Change Request: Make myString.hasPrefix("") and myString.hasSuffix("") return true
[2]: [SR-2131] The empty string is not a prefix/suffix of itself (or any string) · Issue #44739 · apple/swift · GitHub

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

--
-Dave

Sorry to bump this old thread, but is it the expected behavior? :flushed:

"foo".contains("")
// false

All the other modern language I use (Kotlin, Python, etc.) returns true.

This depends on whether Foundation is imported. We have:

"foo".contains("") // ⟹ true

but

import Foundation
"foo".contains("") // ⟹ false

This is not expected.

14 Likes

Thanks for clarifying! Is there anything we can do from the Swift STL or open Foundation side, apart from filing a bug report for Apple's Foundation?

IMO it makes sense that any string should contain the empty string.

1 Like