Is there a simple way to create a javascript lookup table?
You can index prices in a two dimensional map on page load (with working fiddle).
1) I put the select values in lookup-tables in case you have to preload them:
var tables = {
Colour: ["Blue", "Red"],
Size: ["Small", "Medium", "Large"]
};
2) Here is your price table in array form:
var array = [
{Colour: "Blue", Size: "Small", Price: 45},
{Colour: "Blue", Size: "Medium", Price: 48},
{Colour: "Blue", Size: "Large", Price: 98},
{Colour: "Red", Size: "Small", Price: 65},
{Colour: "Red", Size: "Large", Price: 31}
];
3) Initializing selects (populating values and event 'change'):
for (var key in tables)
if (tables.hasOwnProperty(key)) {
selects[key] = form[key];
selects[key].addEventListener("change", updateSpan);
var values = tables[key];
len = values.length;
for (i = 0; i < len; i++) {
var option = document.createElement('option');
option.appendChild(document.createTextNode(values[i]));
form[key].appendChild(option);
}
}
4) Indexing your price table:
len = array.length;
for (i = 0; i < len; i++) {
var record = array[i];
if (typeof map[record.Colour] === 'undefined')
map[record.Colour] = {};
map[record.Colour][record.Size] = record.Price;
}
5) Function updateSpan (on select change):
function updateSpan() {
var Colour = selects.Colour.options[selects.Colour.selectedIndex].value;
var Size = selects.Size.options[selects.Size.selectedIndex].value;
if (typeof map[Colour] !== 'undefined' && typeof map[Colour][Size] !== 'undefined')
span.textContent = map[Colour][Size];
else
span.textContent = "Price not defined to Colour: " + Colour + " and Size: " + Size + ".";
}
6) Debugging (hit F12 in Chrome or Firefox to open Console View).
Full indexed table:
console.log(map);
Just the price of 'Blue' & 'Small':
console.log(map['Blue']['Small']); // outputs the value: 45
The most common solution to this is just looping over the array, in O(N) style.
var filter = {Colour: 'blue', Size:'small'};
function matches_filter(filter, item){
//you can also have variations on this function that
//allow for functions, regexes or anything you like in the filter...
for(var key in filter){
if Object.prototype.hasOwnProperty.call(filter, key){
if(item[key] !== filter[key]){
return false;
}
}
}
return true;
}
var filtered_items = [];
for(var i=0; i<items.length; i++){
var item = items[i];
if(matches_filter(filter, item)){
filtered_items.push(item);
}
}
The reasoning behind the brute forcing is that if you have a data set that is large enough to require a better algorithm then there is a good chance it would be best to just send the query back to the server and have its database do the hard work for you.
For a more complete example you can check this code from the Dojo toolkit.