Last active
August 29, 2015 14:02
-
-
Save numist/e07c49065b6e08a7ee73 to your computer and use it in GitHub Desktop.
A quick implementation of Sets along with some operators for performing some set arithmetic.
This file contains 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
var thing = Set<String>() | |
thing.add("Hello") | |
thing.add(", ") | |
thing.add("World") | |
thing.add("!") | |
thing.remove("World") | |
thing.remove("!") | |
let bar: Set = ["Hello", "World", "!"] | |
println("thing: \(thing.description)") // thing: {"Hello", ", "} | |
println("bar: \(bar.description)") // bar: {"Hello", "World", "!"} | |
println("thing + bar: \((thing + bar).description)") // thing + bar: {"Hello", ", ", "World", "!"} | |
println("thing - bar: \((thing - bar).description)") // thing - bar: {", "} | |
println("thing ^ bar: \((thing ^ bar).description)") // thing ^ bar: {", ", "World", "!"} | |
println("thing & bar: \((thing & bar).description)") // thing & bar: {"Hello"} |
This file contains 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
import Foundation | |
struct SetGenerator<T:Hashable> : Generator { | |
var backingGenerator: DictionaryGenerator<T, Void> | |
init(backingGenerator: DictionaryGenerator<T, Void>) { | |
self.backingGenerator = backingGenerator; | |
} | |
mutating func next() -> T? { | |
if let (key, _) = backingGenerator.next() { | |
return key; | |
} | |
return nil; | |
} | |
} | |
struct Set<T:Hashable> : Sequence, ArrayLiteralConvertible, Printable, DebugPrintable { | |
static func convertFromArrayLiteral(elements: T...) -> Set<T> { | |
var result = Set<T>() | |
for i in elements { | |
result.add(i); | |
} | |
return result; | |
} | |
var _backingStore:Dictionary<T,Void> = [:] | |
var count:Int { return _backingStore.count } | |
var description:String { | |
var result = "{" | |
for key in _backingStore.keys { | |
result += "\"\(key)\", " | |
} | |
result = result.substringToIndex(countElements(result) - 2) + "}" | |
return result | |
} | |
var debugDescription: String { return description } | |
subscript (object: T) -> T? { | |
if _backingStore[object] != nil { | |
return object | |
} | |
return nil | |
} | |
func generate() -> SetGenerator<T> { | |
return SetGenerator(backingGenerator:_backingStore.generate()) | |
} | |
mutating func add(object: T) { | |
_backingStore[object] = () | |
} | |
mutating func remove(object: T) { | |
_backingStore[object] = nil | |
} | |
} | |
func +<T>(lhs: Set<T>, rhs: Set<T>) -> Set<T> { | |
var result = lhs | |
for i in rhs { | |
result.add(i) | |
} | |
return result | |
} | |
func -<T>(lhs: Set<T>, rhs: Set<T>) -> Set<T> { | |
var result = lhs | |
for i in rhs { | |
result.remove(i) | |
} | |
return result | |
} | |
func |<T>(lhs: Set<T>, rhs: Set<T>) -> Set<T> { | |
return lhs + rhs | |
} | |
// This could be more efficiently implemented, but this representation is simpler | |
func &<T>(lhs: Set<T>, rhs: Set<T>) -> Set<T> { | |
return (lhs + rhs) - (lhs ^ rhs) | |
} | |
// This could be more efficiently implemented, but this representation is simpler | |
func ^<T>(lhs: Set<T>, rhs: Set<T>) -> Set<T> { | |
return (lhs - rhs) + (rhs - lhs) | |
} | |
// This could be more efficiently implemented, but this representation is simpler | |
func ==<T>(lhs: Set<T>, rhs: Set<T>) -> Bool { | |
return (lhs - rhs).count == 0 | |
} | |
// This could be more efficiently implemented, but this representation is simpler | |
func !=<T>(lhs: Set<T>, rhs: Set<T>) -> Bool { | |
return (lhs - rhs).count != 0 | |
} | |
@assignment func +=<T>(inout lhs: Set<T>, rhs: Set<T>) { | |
lhs = lhs + rhs | |
} | |
@assignment func -=<T>(inout lhs: Set<T>, rhs: Set<T>) { | |
lhs = lhs - rhs | |
} | |
@assignment func |=<T>(inout lhs: Set<T>, rhs: Set<T>) { | |
lhs = lhs | rhs | |
} | |
@assignment func &=<T>(inout lhs: Set<T>, rhs: Set<T>) { | |
lhs = lhs & rhs | |
} | |
@assignment func ^=<T>(inout lhs: Set<T>, rhs: Set<T>) { | |
lhs = lhs ^ rhs | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment