Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Defaultdict equivalent in javascript

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 value.

Can you do the same in javascript/jquery

like image 723
user462455 Avatar asked Oct 01 '13 23:10

user462455


People also ask

What is the difference between dict and Defaultdict?

The main difference between defaultdict and dict is that when you try to access or modify a key that's not present in the dictionary, a default value is automatically given to that key . In order to provide this functionality, the Python defaultdict type does two things: It overrides .

What does the Defaultdict () function do?

A defaultdict works exactly like a normal dict, but it is initialized with a function (“default factory”) that takes no arguments and provides the default value for a nonexistent key. A defaultdict will never raise a KeyError. Any key that does not exist gets the value returned by the default factory.

How do you declare a Defaultdict?

A defaultdict can be created by giving its declaration an argument that can have three values; list, set or int. According to the specified data type, the dictionary is created and when any key, that does not exist in the defaultdict is added or accessed, it is assigned a default value as opposed to giving a KeyError .

What does Defaultdict mean?

defaultdict means that if a key is not found in the dictionary, then instead of a KeyError being thrown, a new entry is created. The type of this new entry is given by the argument of defaultdict.


2 Answers

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) // [] 
like image 172
Andy Carlson Avatar answered Sep 22 '22 08:09

Andy Carlson


Check out pycollections.js:

var collections = require('pycollections');  var dd = new collections.DefaultDict(function(){return 0}); console.log(dd.get('missing'));  // 0  dd.setOneNewValue(987, function(currentValue) {   return currentValue + 1; });  console.log(dd.items()); // [[987, 1], ['missing', 0]] 
like image 23
Brian Weidenbaum Avatar answered Sep 22 '22 08:09

Brian Weidenbaum