Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
JavaScript
Branch: master
Failed to load latest commit information.
README.md Update README.md
defaultdict.js Fixed toObject to return nested defaultdicts

README.md

JavaScript-Defaultdict

This project tries to emulate the python dictionary class defaultdict.

Simple usage

var addressMap = defaultdict('Unknown');

addressMap['bob'] = 'CA';

console.log(addressMap.bob); //CA
console.log(addressMap('bob')); //CA

console.log(addressMap('jil')); //Unknown

//the default value will be assigned to the key

console.log(addressMap.jil); //Unknown    


addressMap = addressMap.toObject(); // {bob:'CA',jil:'Unknown'}

Functions as a defaultvalue

var presents = ['shoes','phone','tv','xbox'];

var presentsMap = defaultdict(function(){return presents.pop();});

presentsMap['bob'] = 'computer';

console.log(presentsMap('bob')); // computer

console.log(presentsMap('jil')); // xbox

console.log(presentsMap('alice')); // tv

Advanced usage with nested defaultdicts

Suppose we have a records stored somewhere that are in this format

STATE               CITY                        MAKE
CA              San Francisco                   Ford
CA              San Francisco                   Ford
CA              San Francisco                   BWM
CA              San Jose                        Lexus
FL              Miami                           Honda
......

And we wanted to to get make an object that has the counts of each make organized by state, and city. That would look something like

var carsInEachCity = {
    'CA':{
        'San Francisco':{
            'Ford':2000,
            'Nissan': 400,
            'Honda': 5
        },
        'San Jose':{
            'BMW': 7575,
            'Lexus': 56
        }
    },
    'FL':{
        'Miami':{
            'Ford':2000,
            'Nissan': 400,
            'Honda': 5
        },

        'Orlando':{
            'Ford':23,
            'Nissan': 897,
            'Honda': 52,
            'GM': 3456
        }   
    }
}

Usually one would loop through the records and do something like

var carsInEachCity = {};

var records = [
                {state:'CA',city:'San Jose',make:'BMW'},
                {state:'CA',city:'San Jose',make:'BMW'},
                {state:'CA',city:'San Jose',make:'Honda'},
                {state:'FL',city:'Miami',make:'Honda'},
                {state:'FL',city:'Miami',make:'Lexus'},
                {state:'CA',city:'San Jose',make:'BMW'},
                {state:'CA',city:'San Jose',make:'BMW'},
              ];

records.forEach(function(o){

    if(!carsInEachCity[o.state])
        carsInEachCity[o.state] = {};

    if(!carsInEachCity[o.state][o.city])
        carsInEachCity[o.state][o.city] = {};

    if(!carsInEachCity[o.state][o.city][o.make])
        carsInEachCity[o.state][o.city][o.make] = 0;

    carsInEachCity[o.state][o.city][o.make]++;

});

console.log(carsInEachCity);
console.log(carsInEachCity['CA']['San Jose']['BMW']) //4
console.log(carsInEachCity['CA']['San Jose']['Jeep']) //undefined

You can imagine the code getting pretty ugly the more nested things get

To do the same thing with default dict

var carsInEachCity = defaultdict(function () {
    return defaultdict(function () {
        return defaultdict(0);
    });
});

var records = [
                {state:'CA',city:'San Jose',make:'BMW'},
                {state:'CA',city:'San Jose',make:'BMW'},
                {state:'CA',city:'San Jose',make:'Honda'},
                {state:'FL',city:'Miami',make:'Honda'},
                {state:'FL',city:'Miami',make:'Lexus'},
                {state:'CA',city:'San Jose',make:'BMW'},
                {state:'CA',city:'San Jose',make:'BMW'},
            ];


records.forEach(function(o){
    carsInEachCity(o.state)(o.city)(o.make);
    carsInEachCity[o.state][o.city][o.make]++;  
});


console.log(carsInEachCity['CA']['San Jose']['BMW']) //4
console.log(carsInEachCity['CA']['San Jose']['Jeep']) //undefined
console.log(carsInEachCity('CA')('San Jose')('Jeep')) //0
console.log(carsInEachCity['CA']['San Jose']['Jeep']) //0

carsInEachCity = carsInEachCity.toObject();

console.log(carsInEachCity);
console.log(carsInEachCity['CA']['San Jose']['BMW']) //4
console.log(carsInEachCity['CA']['San Jose']['Jeep']) //0

As you can see using defaultdict makes initializing nested objects a breeze.

Tips

If you have nested default dicts the toObject method will call the toObject method on the nested default dicts as well.

Something went wrong with that request. Please try again.