Web DevCenter
oreilly.comSafari Books Online.Conferences.
MySQL Conference and Expo April 14-17, 2008, Santa Clara, CA

Sponsored Developer Resources

Web Columns
Adobe GoLive
Essential JavaScript
Megnut

Web Topics
All Articles
Browsers
ColdFusion
CSS
Database
Flash
Graphics
HTML/XHTML/DHTML
Scripting Languages
Tools
Weblogs

Atom 1.0 Feed RSS 1.0 Feed RSS 2.0 Feed

Learning Lab






O'Reilly Book Excerpts: JavaScript & DHTML Cookbook

Cooking with JavaScript & DHTML, Part 2

Related Reading

JavaScript & DHTML Cookbook
Solutions and Example for Web Programmers
By Danny Goodman

by Danny Goodman

Editor's note: This week's sample recipe, excerpted from JavaScript & DHTML Cookbook, comes from Chapter 3 on "Arrays and Objects." Learn how to simulate a hash table for fast array lookup, giving you the ability to iterate through a collection when you need to use every entry, and to dive into a specific record without any looping. And be sure to check back to this space next week for a recipe on detecting object property and method support.

Recipe 3.9: Simulating a Hash Table for Fast Array Lookup

NN 4, IE 4

Problem

You want to be able to go directly to an entry in an array (especially an array of objects or multidimensional array) without having to loop through the entire array in search of that item.

Solution

By taking advantage of the fact that a JavaScript array is a JavaScript object, you can define properties for an array without interfering with the true array portion of the object. Properties can be referenced by name either by string (in parentheses, like array index value) or following a period like a typical object property.

The key to implementing this construction for an existing array is that you must generate a property for each entry with a unique value. If you are implementing this for an array of objects, use a property value that is unique for each entry as the hash table lookup index.

As a simple example with the coworker objects created in other recipes of this chapter, we'll assume no two coworkers have the same name. Thus, we'll use the name property of the coworker objects as property names for the hash table. Immediately after the array of coworker objects is populated, we execute the following statements:

for (var i = 0; i < employeeDB.length; i++) {
    employeeDB[employeeDB[i].name] = employeeDB[i];
}

Without the hash table, to find the age of a coworker, you have to loop through the employeeDB array in search of a match against the name property of each entry. With the simulated hash table, however, simply reference the unique object bearing the name of the person you're looking for, and retrieve the age property of that object:

var JeansAge = employeeDB["Jean"].age;

You typically use the string way of referring to the object because variable lookup information will likely be coming from a text source: a text input box or a string value of a select element.

Discussion

I cannot overemphasize the importance of the uniqueness of the property name. If you unknowingly have two assignments to the same property value, the last one to execute is the one that sticks.

If one property of an object is not enough to make it unique, you may need to combine values to obtain that uniqueness. For example, the following table's data could be made into a convenient array of objects:

Description

Q1

Q2

Q3

Q4

East

2300

3105

2909

4800

Central

1800

1940

2470

4350

West

900

1200

1923

3810

Each cell of numeric data should be its own object, with other properties assisting in identifying the context of the number. For example:

var sales = new Array( );
sales[sales.length] = {period:"q1", region:"east", total:2300};
sales[sales.length] = {period:"q2", region:"east", total:3105};
...
sales[sales.length] = {period:"q4", region:"west", total:3810};

None of the label properties - the properties you'd likely be using to look up sales information - is totally unique. The East region is shared by four objects, and the Q1 period is shared by three objects. But a combination of the region and period names generates a unique identifier for a given object. Thus, if we use a name of the form region_period (e.g., east_q1), other scripts can perform lookups to reach individual records. Therefore, the hash table maker comes after the object creation statements above:

for (var i = 0; i < sales.length; i++) {
    sales[sales[i].region + "_" + sales[i].period] = sales[i];
}

To access the third quarter sales for the central region, use the following reference:

sales["central_q3"].total

When a hash table entry is assigned a reference to an object (as happens in the preceding examples), each hash table entry simply points to the original object without duplicating the data. Any change you assign to an object's property in the array of objects is reflected in the hash table reference to that object's property.

Any time you have a large multidimensional array or collection of objects through which your scripts will be looking for matching records, try to add the simulated hash table to your array. It gives you the best of both worlds: the ability to iterate through the collection when you need to use every entry, and the ability to dive into a specific record without any looping.

See Also

Recipe 8.13, Recipe 10.8, and Recipe 14.5 for real-world examples of the simulated hash table in action.

Danny Goodman has been writing about technology and computers full-time since 1981 and is the author of Dynamic HTML: The Definitive Reference and "The Complete HyperCard Handbook."


Return to the Web Development DevCenter.