[swift-users] Lazily populated dictionary
Donnacha Oisín Kidney
oisin.kidney at gmail.com
Mon Dec 28 13:34:26 CST 2015
This version kind of mirrors Python’s defaultdict:
final class DefaultDict<Key: Hashable, Value>: CollectionType, CustomStringConvertible {
private var store: [Key:Value]
private let factory: Key -> Value
subscript(i: DictionaryIndex<Key,Value>) -> (Key,Value) {
return store[i]
}
var startIndex: DictionaryIndex<Key,Value> { return store.startIndex }
var endIndex: DictionaryIndex<Key,Value> { return store.endIndex }
func generate() -> DictionaryGenerator<Key,Value> {
return store.generate()
}
subscript(key: Key) -> Value {
get {
if let x = store[key] { return x }
let x = factory(key)
self.store[key] = x
return x
} set {
store[key] = newValue
}
}
init(_ def: Value) {
self.store = [:]
self.factory = { _ in def }
}
init(_ fac: Key -> Value) {
self.store = [:]
self.factory = fac
}
init(_ fac: () -> Value) {
self.store = [:]
self.factory = { _ in fac() }
}
var description: String { return store.description }
}
let dict = DefaultDict<Character,Int>(0)
for c in "abcdgeaaa".characters { dict[c] += 1 }
dict // ["b": 1, "e": 1, "a": 4, "g": 1, "d": 1, "c": 1]
> On 28 Dec 2015, at 19:26, Erica Sadun via swift-users <swift-users at swift.org> wrote:
>
> Maybe something like this?
>
> struct KeyedLazyCache<T: Hashable, U> {
> var backingDictionary: Dictionary<T, U>
> var builderDictionary: Dictionary<T, () -> U>
> mutating func clear() {backingDictionary.removeAll()}
> mutating func valueForKey(key: T) -> U? {
> if let value = backingDictionary[key] {return value}
> if let builder = builderDictionary[key] {
> let value = builder()
> backingDictionary[key] = value
> return value
> }
> return nil
> }
> }
>
> -- E
>
>> On Dec 28, 2015, at 11:36 AM, Rudolf Adamkovič via swift-users <swift-users at swift.org <mailto:swift-users at swift.org>> wrote:
>>
>> Hi there!
>>
>> In my app, I have a very simple class that serves as a key-value cache. The whole thing is basically a lazily populated [String: AVAudioPCMBuffer] dictionary with a String -> AVAudioPCMBuffer function that generates values as needed:
>>
>> final class PlayerAudioCache {
>>
>> // MARK: Retrieving audio buffers
>>
>> func audioBufferForAssetWithName(name: String) -> AVAudioPCMBuffer? {
>> addAudioBufferForAssetWithNameIfNeeded(name)
>> return cachedAudioBuffers[name]
>> }
>>
>> // MARK: Adding audio buffers
>>
>> func addAudioBufferForAssetWithNameIfNeeded(name: String) {
>> guard cachedAudioBuffers[name] == nil else { return }
>> addAudioBufferForAssetWithName(name)
>> }
>>
>> private func addAudioBufferForAssetWithName(name: String) {
>> guard let dataAsset = NSDataAsset(name: name) else { fatalError() }
>> cachedAudioBuffers[name] = dataAsset.map { URL -> AVAudioPCMBuffer in
>> AVAudioPCMBuffer(contentsOfURL: URL)!
>> }
>> }
>>
>> private var cachedAudioBuffers: [String: AVAudioPCMBuffer] = [:]
>>
>> }
>>
>> I feel like there is a pre-made type in Swift’s standard library for what I’m doing here. Am I right?
>>
>> Ideas? Pointers?
>>
>> Thank you!
>>
>> R+
>>
>> _______________________________________________
>> swift-users mailing list
>> swift-users at swift.org <mailto:swift-users at swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-users <https://lists.swift.org/mailman/listinfo/swift-users>
>
> _______________________________________________
> swift-users mailing list
> swift-users at swift.org <mailto:swift-users at swift.org>
> https://lists.swift.org/mailman/listinfo/swift-users <https://lists.swift.org/mailman/listinfo/swift-users>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20151228/f230d4c3/attachment.html>
More information about the swift-users
mailing list