Search code examples
javascripttrie

Dynamically assigning properties to a JavaScript object (trie)


I'm trying to implement a variation of a trie in JavaScript. Basically, it's an efficient data storage object in which the characters in keys are not repeated. In other words, if I have the keys "abe" and "ann," only one instance of the shared letter "a" should appear:

{
    a: {
        b: {
            e: {
                0: 'lincoln'
            }
        },
        n: {
            n: {
                0: 'mcgee'
            }
        }
    }
}

Here is the desired implementation and a few usage examples:

function Trie () {
    // The top level of the trie. 
    var root = {}; 

    return {
        write: function (key, value) {
        },
        read: function (key) {
        }
    };
}

// Sample usage 
var trie = new Trie(); 

trie.write('abe', 'lincoln'); 
trie.write('ann', 'mcgee'); 

trie.read('abe'); // returns 'lincoln'
trie.read('ann'); // returns 'mcgee' 

I've run into a blocker with respect to the write method. Given a string key such as "abe," I need to assign a property to root['a']['b']['e']. I can't find a way to assign a value to an object property several layers deep when the number of keys and the values of the keys are unknown.

The only solution that comes to mind is, I think, a bad one: placing the path to the value into a string and using eval. For example: eval("root['a']['b']['e'] = 'lincoln'");

Is there a better solution for dynamically assigning the values? (I realize that this is a bit of complicated problem, so I'm happy to clarify by providing extra information.)


Solution

  • a very naive approach (given the requirements,though i would write a different implementation)

    given a string of keys and a pointer to the root,and a value to assign;

    function write(root,path,value){
        var a = path.split(''); // 'abc'->['a','b','c']
        var pointer = root;
        var i=0;
        while(i<a.length-1){
            if(pointer[a[i]] == undefined){
               pointer[a[i]]={};
            }
            pointer = pointer[a[i]];
            i++;
        }
        pointer[a[i]]=value;
        return root;
    }
    

    EDIT : i'm assuming all the keys exist on their respective object. I added a if condition in case some keys are not defined.

    EDIT:2 split corrected, correcting a little bug right now ;)

    EDIT:3 should work now.

    usage : write({},'abc',1) // yields {a:{b:{c:1}}}