Last active
November 12, 2018 12:28
-
-
Save natecook1000/3cbe7710ec0002588feed8512468dfc6 to your computer and use it in GitHub Desktop.
ContainmentSet & PredicateSet
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| protocol ContainmentSet { | |
| associatedtype SetElement | |
| func contains(_ element: SetElement) -> Bool | |
| func intersection(_: Self) -> Self | |
| func union(_: Self) -> Self | |
| func subtracting(_: Self) -> Self | |
| func symmetricDifference(_: Self) -> Self | |
| } | |
| extension Set : ContainmentSet { | |
| typealias SetElement = Element | |
| } | |
| struct PredicateSet<T> : ContainmentSet { | |
| func contains(_ element: T) -> Bool { | |
| return predicate(element) | |
| } | |
| func symmetricDifference<U: ContainmentSet>(_ other: U) -> PredicateSet<T> | |
| where U.SetElement == T { | |
| return PredicateSet { e in self.contains(e) != other.contains(e) } | |
| } | |
| func subtracting<U: ContainmentSet>(_ other: U) -> PredicateSet<T> | |
| where U.SetElement == T { | |
| return PredicateSet { e in self.contains(e) && !other.contains(e) } | |
| } | |
| func union<U: ContainmentSet>(_ other: U) -> PredicateSet<T> | |
| where U.SetElement == T { | |
| return PredicateSet { e in self.contains(e) || other.contains(e) } | |
| } | |
| func intersection<U: ContainmentSet>(_ other: U) -> PredicateSet<T> | |
| where U.SetElement == T { | |
| return PredicateSet { e in self.contains(e) && other.contains(e) } | |
| } | |
| func invert() -> PredicateSet { | |
| return PredicateSet { e in !self.contains(e) } | |
| } | |
| let predicate: (T) -> Bool | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // --------------------------------------------- | |
| // Basic usage | |
| let evens = PredicateSet { $0 % 2 == 0 } | |
| evens.contains(3) // f | |
| evens.contains(4) // t | |
| let positives = PredicateSet { $0 > 0 } | |
| let evenPositives = evens.intersection(positives) | |
| evenPositives.contains(4) // t | |
| evenPositives.contains(-4) // f | |
| let s: Set = [1, 2, 3] | |
| let evensPlus123 = evens.union(s) | |
| evensPlus123.contains(3) // t | |
| evensPlus123.contains(4) // t | |
| // --------------------------------------------- | |
| // Semi-replacement for (NS)CharacterSet | |
| typealias CharSet = PredicateSet<Character> | |
| extension PredicateSet where T == Character { | |
| static var whitespace: PredicateSet { | |
| // This is almost certainly wrong | |
| return PredicateSet { e in [" ", "\r", "\n", "\t"].contains(e) } | |
| } | |
| } | |
| extension String { | |
| func trimming(charactersIn set: CharSet) -> Substring { | |
| guard let i = index(where: set.invert().contains) | |
| else { return self.prefix(0) } | |
| let j = indices.reversed().index(where: { !set.contains(self[$0]) })!.base | |
| return self[i..<j] | |
| } | |
| } | |
| " Hello! \n".trimming(charactersIn: .whitespace) | |
| // "Hello!" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment