Skip to content

Instantly share code, notes, and snippets.

@chriswebb09
Created May 11, 2017 04:32
Show Gist options
  • Save chriswebb09/754c3dbc69671a953c4ff03dbbc690e5 to your computer and use it in GitHub Desktop.
Save chriswebb09/754c3dbc69671a953c4ff03dbbc690e5 to your computer and use it in GitHub Desktop.
class HashElement<T: Hashable, U> {
var key: T
var value: U?
init(key: T, value: U?) {
self.key = key
self.value = value
}
}
struct HashTable<Key: Hashable, Value> {
typealias Element = HashElement<Key, Value>
typealias Bucket = [Element]
var buckets: [Bucket]
init(capacity: Int) {
assert(capacity > 0)
buckets = Array<Bucket>(repeatElement([], count: capacity))
}
func index(for key: Key) -> Int {
return abs(key.hashValue) % buckets.count
}
func value(for key: Key) -> Value? {
let index = self.index(for: key)
for element in buckets[index] {
if element.key == key {
return element.value
}
}
return nil
}
subscript(key: Key) -> Value? {
get {
return value(for: key)
}
set {
if let value = newValue {
updateValue(value, forKey: key)
} else {
removeValue(for: key)
}
}
}
@discardableResult
mutating func updateValue(_ value: Value, forKey key: Key) -> Value? {
let index = self.index(for: key)
for (i, element) in buckets[index].enumerated() {
if element.key == key {
let oldValue = element.value
buckets[index][i].value = value
return oldValue
}
}
buckets[index].append(HashElement(key: key, value: value))
return nil
}
@discardableResult
mutating func removeValue(for key: Key) -> Value? {
let index = self.index(for: key)
for (i, element) in buckets[index].enumerated() {
if element.key == key {
buckets[index].remove(at: i)
return element.value
}
}
return nil
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment