
Data Structures in JavaScript - shawndumas
http://blog.benoitvallon.com/category/data-structures-in-javascript/
======
drabiega
It looks like this is a teaching exercise more than anything, but it should be
noted that the implementations are not great. For instance, the set uses an
array based implementation instead of hash based.

In JavaScript the hash based implementation is pretty trivial to write and
some quick testing in node shows that it is dramatically faster.

~~~
vkjv
Unless by "hash based" you mean just using `new Set()`, I'm not aware of a way
to do this generically. Using a `{}` for this would only work for a set of
strings and things that can be uniquely coerced into strings. Otherwise,
looping over arrays is your only option.

Care to elaborate?

~~~
nkoren
> Using a `{}` for this would only work for a set of strings and things that
> can be uniquely coerced into strings.

The code they use has the same limitation. It adds / removes / ensures the
uniqueness of elements in the set by using Array.indexOf(...), which only
works for strings and things that can be uniquely coerced into strings.

So, given this limitation, using an Object-based set would be vastly more
performant.

~~~
dsp1234

      var set = []
      var foo = {foot: 1}
      var bar = {bart: 2}
      set.push(foo)
      set.indexOf(foo) //0
      set.indexOf(bar) //-1
    

"indexOf() compares searchElement to elements of the Array using strict
equality (the same method used by the ===, or triple-equals, operator)."[0]

MDN has the link to the ES5 specification, but the key part is 9(c)(ii):

"Let same be the result of applying the Strict Equality Comparison Algorithm
to searchElement and elementK."

[0] - [https://developer.mozilla.org/en-
US/docs/Web/JavaScript/Refe...](https://developer.mozilla.org/en-
US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf)

~~~
nkoren
Hmm, and yet:

    
    
       var elem = {foo:"bar"}
       var set = [elem]
       set.indexOf(elem) // 0
       set.indexOf({foo:"bar"}) // -1
    

So I guess the strict equality comparison is using some kind of internal
objectId rather than the property name and values of the objects? I guess
depend on how you want to define "uniqueness" for your set...

~~~
dsp1234
Objects in JavaScript use referential equality when checking for strict
equality, which indexOf uses. In your code, 'elem' and '{foo:"bar"}' are
different objects which is why your code doesn't work as expected.

So

    
    
      var x = {foo:"bar"}
      var y = {foo:"bar"}
      var z = x
      x === y //false
      x === z //true
    

This is specified in the ES3 document[0] at 11.9.6(13):

"13\. Return true if x and y refer to the same object or if they refer to
objects joined to each other (see 13.1.2). Otherwise, return false."

[0] - [http://www.ecma-international.org/publications/files/ECMA-
ST...](http://www.ecma-international.org/publications/files/ECMA-ST-
ARCH/ECMA-262,%203rd%20edition,%20December%201999.pdf)

------
eastbayjake
It seems like cheating to do a Hash Table using JavaScript objects, since it's
basically giving you all the hashing magic for free. It'd be cool if the
example actually used an array and a hash function -- even a black box one --
to show how collisions and lookups are handled. (When I've implemented Hash
Tables in JavaScript in the past, I've also included functionality to rehash
the entire table into a larger array as it gets more than 25-50% full... but
can't remember off the top of my head what's the mathematically optimal point
to rehash.)

~~~
masklinn
> When I've implemented Hash Tables in JavaScript in the past, I've also
> included functionality to rehash the entire table into a larger array as it
> gets more than 25-50% full... but can't remember off the top of my head
> what's the mathematically optimal point to rehash.

The load factor (entries/bucket before you resize) varies greatly depending on
the hashmap's addressing and collision resolution. Robin-hood hashing allows
ridiculously high open-addressing load factors for instance (above 0.9 on an
open-addressing linear-probed map, an open-addressing hash table can't go
beyond 1), meanwhile separate-chaining allows load factors way above 1
(buckets are sequences and conflicting entries are appended to the sequence)

------
gravypod
I've been toying around with the idea in my head of building a small OS kernel
in Javascript. I'd use grub to boot into it, ductape [0] to start an os.js or
something, and then just implement everything from there.

These data-structure implementations make me feel that, even though it is
crazy, it might just work. This seems to have come out very clean and easy to
implement.

[0] - [http://duktape.org/](http://duktape.org/)

~~~
woah
But why?

~~~
gravypod
It would be simple to get anyone into OS development. The only easier language
I can find to teach someone is Python, and that doesn't have such an easily
portable runtime.

JavaScript is great because you can learn it in the afternoon and master it in
a few years and has a nice subset of lisp-like features.

It would be a toy to prototype in. Easy to use, and easy to modify. Nothing
serious.

~~~
srpeck
Check out [https://github.com/NodeOS/NodeOS](https://github.com/NodeOS/NodeOS)

~~~
gravypod
I just spent a few minutes looking around that and it seems like it has a lot
of extra stuff piled on to make it easier for experienced developers, but that
would inversely effect someone like me.

I looked around in there and have no idea how any of that works or how any of
the modules relate.

