What is the best/most elegant way to abstract out the conversion of units of measures in the client, based on a user-preferred unit of measure setting?
For example,
Here's something extensible and terse that builds a lookup table so performance should be good.
core = {};
core.mixin = function (dst, src) { if (src) for (var i in src) dst[i] = src[i]; return dst; }
function UnitConverter(meter) {
var feetPerMeter = 3.2808399, feetPerMile = 5280;
this.meter = core.mixin({ km: 1000, mi: feetPerMile / feetPerMeter, ft: 1 / feetPerMeter, m: 1 }, meter);
var t = [], i = 0;
for (t[i++] in this.meter);
this.table = [];
for (i = 0; i < t.length; i++)
for (j = 0; j < t.length; j++) {
var key1 = t[i], key2 = t[(i + j + 1) % t.length];
this.table[key1 + "/" + key2] = this.meter[key2] / this.meter[key1];
}
};
with(UnitConverter) {
prototype = new Object();
prototype.convert = function () {
switch (arguments.length) {
case 1:
return this.table[arguments[0]];
case 2:
return arguments[0] * this.table[arguments[1]];
case 3:
return arguments[0] * this.meter[arguments[1]] / this.meter[arguments[2]];
}
return Number.NaN;
}
}
Usage
Number.converter = new UnitConverter({ nm: 1852 }); // extent to include nautical miles
Number.units = Number.converter.table;
var km = 1;
var mi = km * Number.units["mi/km"];
var m = Number.converter.convert(mi, "mi", "m");
var ft = Number.converter.convert(m, "ft/m");
m = Number.converter.convert(ft, "ft", "m");
ft = m / Number.converter.convert("m/ft");
km = ft * Number.units["km/ft"];
nm = Number.converter.convert(km, "km", "nm");
You might check out this port of Ruby Units to Javascript:
https://github.com/gentooboontoo/js-quantities