Unit of Measure Conversion Library

前端 未结 8 2160
面向向阳花
面向向阳花 2020-12-07 15:15

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,

8条回答
  •  再見小時候
    2020-12-07 15:35

    I'll just leave this here ...

    Simple JS Method to Convert almost ALL Imperial/Standard measurements of Distance/Length

    ;;if (!window.hasOwnProperty('convertImperialMetric')) {
        function convertImperialMetric () {
            var metrics = convertImperialMetric.metrics,
                imperials = convertImperialMetric.imperials,
                args = arguments,
                conversionTypes = { imperial: 'imperial', metric: 'metric' },
                toFixed = false, toFixedX = 2,
                intX, typImp, typMet, conType = 'metric',
                $ret;
    
            conversionTypes.i = conversionTypes.imp = conversionTypes.imperial;
            conversionTypes.m = conversionTypes.met = conversionTypes.metric;
    
            function setVarz(c) {
                for (i in c) {
                    var a = c[i];
                    switch (typeof a) {
                        case "boolean":
                            toFixed = a;
                            break;
                        case "number":
                            void 0 == intX ? intX = a : toFixedX = a;
                            break;
                        case "string":
                            isNaN(parseFloat(a)) || void 0 != intX ? imperials.hasOwnProperty(a) ? typImp = a : metrics.hasOwnProperty(a) ? typMet = a : conversionTypes.hasOwnProperty(a) && (conType = conversionTypes[a]) : intX = parseFloat(a);
                            break;
                        case "object":
                            if (a instanceof Array) setVarz.apply(this, [a]);
                            else if (a instanceof Object)
                                for (h in a) {
                                    var b = a[h];
                                    conversionTypes.hasOwnProperty(h) ? conType = conversionTypes[h] : imperials.hasOwnProperty(h) ? (typImp =
                                        h, void 0 != intX || isNaN(parseFloat(b)) || (intX = parseFloat(b))) : metrics.hasOwnProperty(h) ? (typMet = h, void 0 != intX || isNaN(parseFloat(b)) || (intX = parseFloat(b))) : setVarz.apply(this, [
                                        [b]
                                    ])
                                }
                    }
                }
            };
            setVarz(args);
    
            if (!isNaN(parseFloat(intX)) && imperials.hasOwnProperty(typImp) && metrics.hasOwnProperty(typMet) && conversionTypes.hasOwnProperty(conType)) {
                if (conType == 'metric') {
                    var inches = intX * imperials[typImp],
                        centimeters = inches * 2.54;
                    $ret = centimeters * metrics[typMet];
                }
                else if (conType == 'imperial') {
                    var centimeters = intX / metrics[typMet],
                        inches = centimeters / 2.54;
                    $ret = inches / imperials[typImp];
                }
            }
    
            return toFixed ? parseFloat($ret.toFixed(toFixedX)) : $ret;
        }
    
        convertImperialMetric.imperials = {
            inches: 1,
            feet: 12,
            yards: 36,
            miles: 63360,
            nautical: 72913.4
        };
    
        convertImperialMetric.metrics = {
            yocto: 10000000000000000000000,
            zepto: 10000000000000000000,
            atto: 10000000000000000,
            femto: 10000000000000,
            pico: 10000000000,
            nano: 10000000,
            micro: 10000,
            milli: 10,
            centi: 1,
            deci: .1,
            meter: .01,
            deka: .001,
            hecto: .0001,
            kilo: .00001,
            mega: .00000001,
            giga: .00000000001,
            tera: .00000000000001,
            peta: .00000000000000001,
            exa: .00000000000000000001,
            zetta: .00000000000000000000001,
            yotta: .00000000000000000000000001
        };
    }
    

    Example Usages:

    convertImperialMetric(12, 'inches', 'centi');   //  Results in: 30.48
    convertImperialMetric(30.48, 'centi', 'inches', 'i');   //  Results in: 12
    convertImperialMetric('1200000', 'inches', 'kilo'); //  Results in: 30.480000000000004
    convertImperialMetric('1200000', 'inches', 'kilo', true);   //  Results in: 30.48
    convertImperialMetric('1200000', 'inches', 'kilo', true, 1);    //  Results in: 30.5
    convertImperialMetric([ 12, 'inches', 'centi' ]);   //  Results in: 30.48
    convertImperialMetric([ '12', 'inches', 'centi' ]); //  Results in: 30.48
    convertImperialMetric({ inches: 12, anyVariableName: 'centi' });    //  Results in: 30.48
    convertImperialMetric({ inches: '12', anyVariableName: 'centi' });  //  Results in: 30.48
    convertImperialMetric({ inches: 12, centi: 'anyValue' });   //  Results in: 30.48
    convertImperialMetric({ inches: '12', centi: 'anyValue' }); //  Results in: 30.48
    convertImperialMetric({ inches: '12', to: 'centi', type: 'metric', toFixed: true, toFX: 1 });   //  Results in: 30.5
    convertImperialMetric({ feet: 1 }, 'centi');    //  Results in: 30.48
    convertImperialMetric({ centi: '30.48' }, 'inches', 'imperial');    //  Results in: 12
    convertImperialMetric({ meter: '.3048' }, 'inches', 'imperial');    //  Results in: 12
    

    jsFiddle / jsFiddle/show

提交回复
热议问题