I defined an onlyIfNotIn function for this one use case I had where I wanted to use contains() more naturally and in a chained expression:
let foos = things.compactMap({ $0.foo?.onlyIfNotIn([a,b,c]) })
And then went ahead to complete the extension with the 4 functions: ifIn, ifnotIn, onlyIfIn, onlyIfNotIn. To be honest, they're based on an isIn implementation I saw in this swift forums post, before which I was having trouble getting it right.
More examples:
if n.isIn(1..<10) { print(n) }
let namesOfAllowed = elements.compactMap({$0.onlyIfIn(allowed)?.name})
I omitted for brevity overloads taking variadic Self... in place of sequences, and ones that permit the sequence elements/variadics to be optionals.
See https://gist.github.com/jpmhouston/72eb8e6681b7cc2499ca1c350b5f0c09
Questions:
Is there another way to skin this cat[1], something already commonly used? Rather, if this is unique and useful should it be pitched for the standard library? Do variants using async sequence make sense?
no cats were harmed during this coding exercise ↩︎
To change this from taking an allowed set to a forbidden set:
let namesOfAllowed = elements.compactMap({$0.onlyIfIn(allowed)?.name})
let namesOfAllowed2 = elements.compactMap({$0.onlyIfNotIn(forbidden)?.name})
unless I'm out to lunch there's no place to simply insert a negation (a !), but instead would need to make the expression much more complex.
(i had this example wrong in the original post. will correct there too)
So I don't think there's any other way than to have a negated variant of the function. If they were named includedIn and excludedFrom would that an improvement?
let namesOfAllowed = elements.compactMap({$0.includedIn(allowed)?.name})
let namesOfAllowed2 = elements.compactMap({$0.excludedFrom(forbidden)?.name})
// indeed isIncludedIn can be negated, so there's no need for isExcludedFrom()
if !n.isIncludedIn(1..<10) { print(n) }
Yes of course, .filter { !forbidden.contains($0) } was the other way I was looking for.
Thanks @mayoff, unlessIn is indeed a lot better . Although I may now be more fond of isIncludedIn / includedIn / excludedFrom. Ok, worth keeping to myself (and my gist) but that's about it.
Revisiting this to put my gist to bed at a time when I'm not operating on no sleep, I still see that a reversed contains is eminently desirable if testing only one element in a chain of expressions, ie. not being able to rewrite sequence.compactMap that uses $0.excludedFrom… as sequence.filter…
With only a contained function on the sequence and no chainable contained-by function on the element (what I'm now calling includedIn / excludedFrom) then that has to be written like this maybe:
Has such a inverse-contains function already been pitched and rejected? If no, does anyone want to help me pitch this addition to the the standard library?