Skip to content

Instantly share code, notes, and snippets.

@koher
Created June 22, 2014 11:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save koher/834e0e8b5a19d316b1cf to your computer and use it in GitHub Desktop.
Save koher/834e0e8b5a19d316b1cf to your computer and use it in GitHub Desktop.
Conceptual Implementations of Swift's Array and Dictionary
struct Array2<T> {
var buffer: Buffer<T>
var count: Int
init() {
buffer = Buffer()
count = 0
}
init(_ elements: T...) {
self.init()
for element in elements {
append(element)
}
}
subscript(index: Int) -> T {
get {
return buffer[index]!
}
nonmutating set {
buffer[index] = newValue
}
}
mutating func append(newElement: T) {
if (count == buffer.count) {
let oldBuffer = buffer
buffer = Buffer(max(buffer.count * 2, 1))
for index in 0..count {
buffer[index] = oldBuffer[index]
}
}
buffer[count++] = newElement
}
}
struct Dictionary2<K: Hashable, V> {
var buckets: Buffer<List<(K, V)>>
var count: Int
init() {
buckets = Buffer()
count = 0
}
subscript(key: K) -> V? {
get {
let bucket = buckets[key.hashValue % buckets.count]
if let entries = bucket {
for entry in entries {
if key == entry.0 {
return entry.1
}
}
}
return nil
}
set {
if (count >= buckets.count * 3 / 4) {
let oldBuckets = buckets
buckets = Buffer<List<(K, V)>>(buckets.count * 2 + 1)
for bucketIndex in 0..oldBuckets.count {
let bucket = oldBuckets[bucketIndex]
if let entries = bucket {
for entry in entries {
self[entry.0] = entry.1
}
}
}
}
let bucketIndex = key.hashValue % buckets.count
let bucket = buckets[bucketIndex]
if let entries = bucket {
for (index, entry) in enumerate(entries) {
if key == entry.0 {
if let nonNilNewValue = newValue {
entries[index] = (key, nonNilNewValue)
return
} else {
entries.removeAtIndex(index)
count--
return
}
}
}
if let nonNilNewValue = newValue {
entries.append((key, nonNilNewValue))
count++
}
} else {
if let nonNilNewValue = newValue {
buckets[bucketIndex] = List<(K, V)>((key, nonNilNewValue))
count++
}
}
}
}
}
class Buffer<T> {
let array: Array<T?>
init(_ count: Int) {
self.array = Array(count: count, repeatedValue: nil)
}
convenience init() {
self.init(0)
}
subscript(index: Int) -> T? {
get {
return array[index]
}
set {
array[index] = newValue
}
}
var count: Int {
get {
return array.count
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment