Defaultdict equivalent in javascript

前端 未结 5 1190
小蘑菇
小蘑菇 2020-12-29 22:32

In python you can have a defaultdict(int) which stores int as values. And if you try to do a \'get\' on a key which is not present in the dictionary you get zero as default

5条回答
  •  無奈伤痛
    2020-12-29 23:26

    You can build one using a JavaScript Proxy

    var defaultDict = new Proxy({}, {
      get: (target, name) => name in target ? target[name] : 0
    })
    

    This lets you use the same syntax as normal objects when accessing properties.

    defaultDict.a = 1
    console.log(defaultDict.a) // 1
    console.log(defaultDict.b) // 0
    

    To clean it up a bit, you can wrap this in a constructor function, or perhaps use the class syntax.

    class DefaultDict {
      constructor(defaultVal) {
        return new Proxy({}, {
          get: (target, name) => name in target ? target[name] : defaultVal
        })
      }
    }
    
    const counts = new DefaultDict(0)
    console.log(counts.c) // 0
    

    EDIT: The above implementation only works well with primitives. It should handle objects too by taking a constructor function for the default value. Here is an implementation that should work with primitives and constructor functions alike.

    class DefaultDict {
      constructor(defaultInit) {
        return new Proxy({}, {
          get: (target, name) => name in target ?
            target[name] :
            (target[name] = typeof defaultInit === 'function' ?
              new defaultInit().valueOf() :
              defaultInit)
        })
      }
    }
    
    
    const counts = new DefaultDict(Number)
    counts.c++
    console.log(counts.c) // 1
    
    const lists = new DefaultDict(Array)
    lists.men.push('bob')
    lists.women.push('alice')
    console.log(lists.men) // ['bob']
    console.log(lists.women) // ['alice']
    console.log(lists.nonbinary) // []
    

提交回复
热议问题