Alice, Bob, and Mallory: JavaScript hash table keysmetasyntacticstag:alicebobandmallory.com,2005:TypoTypo2010-10-15T10:53:01+02:00Jonas Elfströmurn:uuid:27e04911-d089-4122-8a96-ad529a9b8b3b2010-03-05T17:42:00+01:002010-10-15T10:53:01+02:00JavaScript hash table keys<p>In JavaScript you can add properties to objects dynamically. You can access those properties both by <code>object.foo</code> and <code>object['foo']</code>. The later is commonly used to use JavaScript objects as <a href="http://en.wikipedia.org/wiki/Hash_table">hash tables</a> (associative arrays).</p>
<p>While implementing <a href="http://stackoverflow.com/questions/2380019/generate-8-unique-random-numbers-between-1-and-100/2380513#2380513">a simplistic unique random number generator</a> I happened to use <a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Object/keys">keys(obj)</a>. Unfortunately <code>keys(obj)</code> is part of <a href="http://en.wikipedia.org/wiki/ECMAScript">ECMAScript</a> 5. See chapter 15.2.3.14 in <a href="http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf">ECMA-262</a>. The web browsers of today mostly implements ECMAScript 3.</p>
<p>Here's an implementation of <code>keys(obj)</code> for ECMAScript 3 browsers (tested in Google Chrome, IE8 and Firefox 3.5). If the browser already has a keys function then nothing will be done.</p>
<table class="CodeRay"><tr>
<td class="line-numbers" title="double click to toggle" ondblclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre><a href="#n1" name="n1">1</a>
<a href="#n2" name="n2">2</a>
<a href="#n3" name="n3">3</a>
<a href="#n4" name="n4">4</a>
<a href="#n5" name="n5">5</a>
<a href="#n6" name="n6">6</a>
<a href="#n7" name="n7">7</a>
<a href="#n8" name="n8">8</a>
<a href="#n9" name="n9">9</a>
</pre></td>
<td class="code"><pre><span style="color:#080;font-weight:bold">if</span> (typeof keys == <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">undefined</span><span style="color:#710">"</span></span>)
{
var keys = function(ob)
{
props=[];
<span style="color:#080;font-weight:bold">for</span> (k in ob) <span style="color:#080;font-weight:bold">if</span> (ob.hasOwnProperty(k)) props.push(k);
<span style="color:#080;font-weight:bold">return</span> props;
}
}</pre></td>
</tr></table>
<p><br/>
The simplistic unique random number generator looks like this</p>
<table class="CodeRay"><tr>
<td class="line-numbers" title="double click to toggle" ondblclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre><a href="#n1" name="n1">1</a>
<a href="#n2" name="n2">2</a>
<a href="#n3" name="n3">3</a>
<a href="#n4" name="n4">4</a>
<a href="#n5" name="n5">5</a>
<a href="#n6" name="n6">6</a>
</pre></td>
<td class="code"><pre>function uniqueRndNumbers(min, max, quantity) {
var ht={}, i=quantity;
<span style="color:#080;font-weight:bold">while</span> ( i><span style="color:#00D">0</span> || keys(ht).length<quantity)
ht[Math.floor(Math.random()*(max-min+<span style="color:#00D">1</span>))+min]=i--;
<span style="color:#080;font-weight:bold">return</span> keys(ht);
}</pre></td>
</tr></table>
<p><br/>
This function has not undergone any serious testing. Also if the <code>quantity</code> is more than a fraction of <code>(max-min)</code> then another algorithm like the <a href="http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher–Yates shuffle</a> might be a better choice.</p><p>In JavaScript you can add properties to objects dynamically. You can access those properties both by <code>object.foo</code> and <code>object['foo']</code>. The later is commonly used to use JavaScript objects as <a href="http://en.wikipedia.org/wiki/Hash_table">hash tables</a> (associative arrays).</p>
<p>While implementing <a href="http://stackoverflow.com/questions/2380019/generate-8-unique-random-numbers-between-1-and-100/2380513#2380513">a simplistic unique random number generator</a> I happened to use <a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Object/keys">keys(obj)</a>. Unfortunately <code>keys(obj)</code> is part of <a href="http://en.wikipedia.org/wiki/ECMAScript">ECMAScript</a> 5. See chapter 15.2.3.14 in <a href="http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf">ECMA-262</a>. The web browsers of today mostly implements ECMAScript 3.</p>
<p>Here's an implementation of <code>keys(obj)</code> for ECMAScript 3 browsers (tested in Google Chrome, IE8 and Firefox 3.5). If the browser already has a keys function then nothing will be done.</p>
<table class="CodeRay"><tr>
<td class="line-numbers" title="double click to toggle" ondblclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre><a href="#n1" name="n1">1</a>
<a href="#n2" name="n2">2</a>
<a href="#n3" name="n3">3</a>
<a href="#n4" name="n4">4</a>
<a href="#n5" name="n5">5</a>
<a href="#n6" name="n6">6</a>
<a href="#n7" name="n7">7</a>
<a href="#n8" name="n8">8</a>
<a href="#n9" name="n9">9</a>
</pre></td>
<td class="code"><pre><span style="color:#080;font-weight:bold">if</span> (typeof keys == <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">undefined</span><span style="color:#710">"</span></span>)
{
var keys = function(ob)
{
props=[];
<span style="color:#080;font-weight:bold">for</span> (k in ob) <span style="color:#080;font-weight:bold">if</span> (ob.hasOwnProperty(k)) props.push(k);
<span style="color:#080;font-weight:bold">return</span> props;
}
}</pre></td>
</tr></table>
<p><br/>
The simplistic unique random number generator looks like this</p>
<table class="CodeRay"><tr>
<td class="line-numbers" title="double click to toggle" ondblclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre><a href="#n1" name="n1">1</a>
<a href="#n2" name="n2">2</a>
<a href="#n3" name="n3">3</a>
<a href="#n4" name="n4">4</a>
<a href="#n5" name="n5">5</a>
<a href="#n6" name="n6">6</a>
</pre></td>
<td class="code"><pre>function uniqueRndNumbers(min, max, quantity) {
var ht={}, i=quantity;
<span style="color:#080;font-weight:bold">while</span> ( i><span style="color:#00D">0</span> || keys(ht).length<quantity)
ht[Math.floor(Math.random()*(max-min+<span style="color:#00D">1</span>))+min]=i--;
<span style="color:#080;font-weight:bold">return</span> keys(ht);
}</pre></td>
</tr></table>
<p><br/>
This function has not undergone any serious testing. Also if the <code>quantity</code> is more than a fraction of <code>(max-min)</code> then another algorithm like the <a href="http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher–Yates shuffle</a> might be a better choice.</p>Jonas Elfströmurn:uuid:ed3d3238-8f43-4c6d-b36b-ae38f5c44c2b2010-10-15T12:47:07+02:002010-10-16T15:29:46+02:00Comment on JavaScript hash table keys by Jonas Elfström<p>Nice catch, fixed. Thanks!</p>Nedurn:uuid:11866833-cfbd-4d18-a744-e0a5c7a1f65f2010-10-14T22:54:38+02:002010-10-21T20:35:26+02:00Comment on JavaScript hash table keys by Ned<p>It looks like you’ve got a copy/paste error in your first snippet. “for (k in ht)” should probably be “for (k in obj)” now that the loop’s been moved to its own function.</p>