Skip to content

Instantly share code, notes, and snippets.

@JadenGeller
Created March 30, 2015 22:13
Show Gist options
  • Save JadenGeller/d368dde68e1df0d5a675 to your computer and use it in GitHub Desktop.
Save JadenGeller/d368dde68e1df0d5a675 to your computer and use it in GitHub Desktop.
Swift Set of "Any" Type
// Examples
var set = AnySet()
set.insert(3)
set.insert("hello")
set.insert("hi")
set.insert(2.3)
set.contains(6) // -> false
set.contains(3) // -> true
set.remove(3)
set.insert(4)
set.contains(3) // -> false
set.contains(4) // -> true
set.isSupersetOf(["hello", "hi"]) // -> true
set.isSubsetOf(["hello", "hi"]) // -> false
// Implementation
struct AnyHashable : Hashable, Printable {
private let backing: Any
private let hashValueClosure: () -> Int
private let equalityClosure: (Any) -> Bool
init<T: Hashable>(_ value: T) {
self.backing = value
self.hashValueClosure = { value.hashValue }
self.equalityClosure = {
if let other = $0 as? T { return value == other }
else { return false }
}
}
var hashValue: Int {
get {
return hashValueClosure()
}
}
private func isEqual(other: AnyHashable) -> Bool {
return equalityClosure(other.backing)
}
var description: String {
get {
return "\(backing)"
}
}
}
func ==(lhs: AnyHashable, rhs: AnyHashable) -> Bool {
return lhs.isEqual(rhs)
}
struct AnySet : Hashable, Printable, DebugPrintable, SequenceType {
private var backing: Set<AnyHashable>
init() {
backing = Set<AnyHashable>()
}
init<T: Hashable>(_ set: Set<T>) {
self.init(LazySequence(set).array)
}
init<T: Hashable>(_ array: [T]) {
self.backing = Set(map(array, { member in AnyHashable(member) }))
}
private init(_ backing: Set<AnyHashable>) {
self.backing = backing
}
mutating func insert<T: Hashable>(member: T) {
backing.insert(AnyHashable(member))
}
func contains<T: Hashable>(member: T) -> Bool {
return backing.contains(AnyHashable(member))
}
mutating func remove<T: Hashable>(member: T) {
backing.remove(AnyHashable(member))
}
mutating func removeAll(keepCapacity: Bool = false) {
backing.removeAll(keepCapacity: keepCapacity)
}
func isSubsetOf<S : SequenceType where S.Generator.Element : Hashable>(sequence: S) -> Bool {
return backing.isSubsetOf(map(sequence, { member in AnyHashable(member) }))
}
func isStrictSubsetOf<S : SequenceType where S.Generator.Element : Hashable>(sequence: S) -> Bool {
return backing.isStrictSubsetOf(map(sequence, { member in AnyHashable(member) }))
}
func isSupersetOf<S : SequenceType where S.Generator.Element : Hashable>(sequence: S) -> Bool {
return backing.isSupersetOf(map(sequence, { member in AnyHashable(member) }))
}
func isStrictSupersetOf<S : SequenceType where S.Generator.Element : Hashable>(sequence: S) -> Bool {
return backing.isStrictSupersetOf(map(sequence, { member in AnyHashable(member) }))
}
func isDisjointWith<S : SequenceType where S.Generator.Element : Hashable>(sequence: S) -> Bool {
return backing.isDisjointWith(map(sequence, { member in AnyHashable(member) }))
}
func union<S : SequenceType where S.Generator.Element : Hashable>(sequence: S) -> AnySet {
return AnySet(backing.union(map(sequence, { member in AnyHashable(member) })))
}
mutating func unionInPlace<S : SequenceType where S.Generator.Element : Hashable>(sequence: S) {
backing.unionInPlace(map(sequence, { member in AnyHashable(member) }))
}
func subtract<S : SequenceType where S.Generator.Element : Hashable>(sequence: S) -> AnySet {
return AnySet(backing.subtract(map(sequence, { member in AnyHashable(member) })))
}
mutating func subtractInPlace<S : SequenceType where S.Generator.Element : Hashable>(sequence: S) {
backing.subtractInPlace(map(sequence, { member in AnyHashable(member) }))
}
func intersect<S : SequenceType where S.Generator.Element : Hashable>(sequence: S) -> AnySet {
return AnySet(backing.intersect(map(sequence, { member in AnyHashable(member) })))
}
mutating func intersectInPlace<S : SequenceType where S.Generator.Element : Hashable>(sequence: S) {
backing.intersectInPlace(map(sequence, { member in AnyHashable(member) }))
}
func exclusiveOr<S : SequenceType where S.Generator.Element : Hashable>(sequence: S) -> AnySet {
return AnySet(backing.exclusiveOr(map(sequence, { member in AnyHashable(member) })))
}
mutating func exclusiveOrInPlace<S : SequenceType where S.Generator.Element : Hashable>(sequence: S) {
backing.exclusiveOrInPlace(map(sequence, { member in AnyHashable(member) }))
}
var count: Int {
get {
return backing.count
}
}
var isEmpty: Bool {
get {
return backing.isEmpty
}
}
var hashValue: Int {
get {
return backing.hashValue
}
}
var description: String {
get {
return backing.description
}
}
var debugDescription: String {
get {
return backing.debugDescription
}
}
private func isEqual(other: AnySet) -> Bool {
return backing == other.backing
}
func generate() -> SetGenerator<AnyHashable> {
return backing.generate()
}
}
func ==(lhs: AnySet, rhs: AnySet) -> Bool {
return lhs.isEqual(rhs)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment