Loosely basing myself on this blog post, I implemented an ordered dictionary. In essence, it's a wrapper struct for a list of tuples with some initialisers and some functions (map, filter, toArray, ...) added to it.
struct OrderedDictionary<KeyType: Hashable, ValueType>: SequenceType
{
typealias KeyValueType = (key:KeyType, value:ValueType)
private var tuples: [KeyValueType] = []
init() {}
init(_ tupleArgs: KeyValueType...)
{
self.init(tupleArgs)
}
init(_ tupleArgs: [KeyValueType])
{
tuples = tupleArgs
}
subscript(key:KeyType) -> ValueType?
{
get
{
return tuples.filter({ $0.key == key })[0].value
}
set(newValue)
{
if let val = newValue
{
if tuples.contains({ $0.key == key })
{
tuples = tuples.map({ $0.key == key ? ($0.key, val) : $0 })
}
else
{
tuples.append((key, val))
}
}
else
{
tuples = tuples.filter({ $0.key != key })
}
}
}
func generate() -> AnyGenerator<KeyValueType>
{
var nextIndex = 0
return anyGenerator({
if nextIndex >= self.tuples.count
{
return nil
}
else
{
return self.tuples[nextIndex++]
}
})
}
mutating func insert(tuple: KeyValueType, atIndex index: Int)
{
tuples = tuples.filter({ $0.key != tuple.key })
tuples.insert(tuple, atIndex: index)
}
func map<NewKeyType:Hashable, NewValueType>(transform: (KeyValueType) -> (key:NewKeyType, value:NewValueType)) -> OrderedDictionary<NewKeyType, NewValueType>
{
return OrderedDictionary<NewKeyType, NewValueType>(tuples.map(transform))
}
func filter(includeElement: (KeyValueType) -> Bool) -> OrderedDictionary<KeyType, ValueType>
{
return OrderedDictionary(tuples.filter(includeElement))
}
func sort(isOrderedBefore: (KeyValueType, KeyValueType) -> Bool) -> OrderedDictionary<KeyType, ValueType>
{
return OrderedDictionary(tuples.sort(isOrderedBefore))
}
func reverse() -> OrderedDictionary<KeyType, ValueType>
{
return OrderedDictionary(tuples.reverse())
}
func toArray<T>(transform:((KeyValueType) -> T)) -> [T]
{
return tuples.map(transform)
}
func toArray() -> [KeyValueType]
{
return tuples
}
func toDict() -> [KeyType:ValueType]
{
var dict: [KeyType:ValueType] = [:]
for tuple in tuples
{
dict[tuple.key] = tuple.value
}
return dict
}
}
Does this look okay? Is it Swift-y enough and are there no major performance issues? I'm a bit worried about the filter, map, reverse and sort functions, but I'm not sure why. I'm also not confident about my use of map in the subscript setter.