[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