Question

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

Was it helpful?

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}}}

OTHER TIPS

what you're looking for is a double array trie. you can do a github search for that, but the two main libraries listed are:

var doublearray = require('./doublearray.js');

var words = [

{ k: 'a', v: 1 },

{ k: 'abc', v: 2 },

];

var trie = doublearray.builder().build(words);

trie.contain('a'); // -> true

trie.lookup('abc'); // -> 2

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top