1

jsFiddle --> http://jsfiddle.net/rVLN2/1/

我是菜鸟 - 我知道我的脚本效率低下,但我正在努力。我有一个对象数组设置,例如:

var SatWaterMetric = [
  {"T":0,"Psat":0.6117,"vf":0.001,"vg":206,"hf":0.001,"hfg":2500.9,"hg":2500.9},
  {"T":5,"Psat":0.8725,"vf":0.001,"vg":147.03,"hf":21.02,"hfg":2489.1,"hg":2510.1},
  {"T":10,"Psat":1.2281,"vf":0.001,"vg":106.32,"hf":42.022,"hfg":2477.2,"hg":2519.2},
  ...................................];

然后我有一个从 html 中提取值并根据表格插入数值的函数。

 function interpolate(myval, unit) {

    if (unit == "T") {
        for (var i=0;i<SatWaterMetric.length;i++) {
            if (myval < SatWaterMetric[i].T) {

                T_low = SatWaterMetric[i-2].T;
                T_high = SatWaterMetric[i-1].T;

                Psat_low = SatWaterMetric[i-2].Psat;
                Psat_high = SatWaterMetric[i-1].Psat;                    

                vf_low = SatWaterMetric[i-2].vf;
                vf_high = SatWaterMetric[i-1].vf;

                vg_low = SatWaterMetric[i-2].vg;
                vg_high = SatWaterMetric[i-1].vg;

                hf_low = SatWaterMetric[i-2].hf;
                hf_high = SatWaterMetric[i-1].hf;

                hfg_low = SatWaterMetric[i-2].hfg;
                hfg_high = SatWaterMetric[i-1].hfg;

                hg_low = SatWaterMetric[i-2].hg;
                hg_high = SatWaterMetric[i-1].hg;

                var factor = (myval - T_low) / (T_high - T_low);

                Psatx = (1 * Psat_low) + ( 1 * factor * (Psat_high - Psat_low));
                vfx = (1 * vf_low) + ( 1 * factor * (vf_high - vf_low)); 
                vgx = (1 * vg_low) + ( 1 * factor * (vg_high - vg_low)); 
                hfx = (1 * hf_low) + ( 1 * factor * (hf_high - hf_low)); 
                hfgx = (1 * hfg_low) + ( 1 * factor * (hfg_high - hfg_low)); 
                hgx = (1 * hg_low) + ( 1 * factor * (hg_high - hg_low));
                Tx = myval;
                break;
            }
        }

        $('#txtpsat').val(Math.round(Psatx*100000)/100000);
        $('#txtvf').val(Math.round(vfx*10000000)/10000000);
        $('#txtvg').val(Math.round(vgx*100000)/100000);
        $('#txthf').val(Math.round(hfx*10000)/10000);
        $('#txthg').val(Math.round(hgx*100)/100);
        $('#txthfg').val(Math.round(hfgx*100)/100);

    } else if (unit == "Psat") {

        //Repeat everything but for Psat

    } else if (unit == "vf") {

        //Repeat everything but for vf

               } else {}
}

});

现在这只是在“T”已知的情况下解决这些值。我正在尝试制作一个程序来确定输入了哪个值(“Psat”、“vg”、“vf”等),然后根据该值评估所有其他数字。按照我现在的设置方式,我基本上必须为 Psat、vg、vf、hg、hf 和 hfg 重复所有这些代码。这似乎非常低效。有没有办法将其缩减为一个平滑函数?.

. jsFiddle --> http://jsfiddle.net/rVLN2/1/

.

4

3 回答 3

4

您缺少 javascript 的一个非常酷的功能。

obj.Prop

是相同的

obj['Prop']

所以,你要做的就是使用单位作为值的键。

于 2013-09-05T19:30:04.127 回答
1

我被它打败了!好吧,无论如何,这是实现...

更改SatWaterMetric[i].TSatWaterMetric[unit]

jsFiddle。_

function interpolate(myval, unit) {
            for (var i=0;i<SatWaterMetric.length;i++) {
                if (myval < SatWaterMetric[i][unit]) {

                    T_low = SatWaterMetric[i-2].T;
                    T_high = SatWaterMetric[i-1].T;

                    Psat_low = SatWaterMetric[i-2].Psat;
                    Psat_high = SatWaterMetric[i-1].Psat;                    

                    vf_low = SatWaterMetric[i-2].vf;
                    vf_high = SatWaterMetric[i-1].vf;

                    vg_low = SatWaterMetric[i-2].vg;
                    vg_high = SatWaterMetric[i-1].vg;

                    hf_low = SatWaterMetric[i-2].hf;
                    hf_high = SatWaterMetric[i-1].hf;

                    hfg_low = SatWaterMetric[i-2].hfg;
                    hfg_high = SatWaterMetric[i-1].hfg;

                    hg_low = SatWaterMetric[i-2].hg;
                    hg_high = SatWaterMetric[i-1].hg;

                    var factor = (myval - T_low) / (T_high - T_low);

                    Psatx = (1 * Psat_low) + ( 1 * factor * (Psat_high - Psat_low));
                    vfx = (1 * vf_low) + ( 1 * factor * (vf_high - vf_low)); 
                    vgx = (1 * vg_low) + ( 1 * factor * (vg_high - vg_low)); 
                    hfx = (1 * hf_low) + ( 1 * factor * (hf_high - hf_low)); 
                    hfgx = (1 * hfg_low) + ( 1 * factor * (hfg_high - hfg_low)); 
                    hgx = (1 * hg_low) + ( 1 * factor * (hg_high - hg_low));
                    Tx = myval;
                    break;
                }
            }

            $('#txtpsat').val(Math.round(Psatx*100000)/100000);
            $('#txtvf').val(Math.round(vfx*10000000)/10000000);
            $('#txtvg').val(Math.round(vgx*100000)/100000);
            $('#txthf').val(Math.round(hfx*10000)/10000);
            $('#txthg').val(Math.round(hgx*100)/100);
            $('#txthfg').val(Math.round(hfgx*100)/100);
    }
于 2013-09-05T19:31:09.917 回答
1

如前所述,您可以利用可以使用点和数组表示法来引用对象的属性这一事实。

更进一步,您不仅可以简化对传入的访问unit,还可以进一步减少其余代码。

首先,通过稍微更改您的标记,所有输入字段 ID 将具有相同的模式“txt”+key.toLowerCase():

<input type='text' size='8' id='txtt'/>

用预定义的大小初始化一个 highLow 值的对象(T 没有):

var highLow = {
    T:    {},
    Psat: {magnitude: 100000},
    vf:   {magnitude: 10000000},
    vg:   {magnitude: 100000},
    hf:   {magnitude: 10000},
    hg:   {magnitude: 100},
    hfg:  {magnitude: 100}
};

然后您的 interpolate 函数的其余部分可以修改为如下所示:

// Note 1: Started loop at 2 to avoid undefined array values
// Note 2: the redundant loops could be reduced by calculating T first
function interpolate(myval, unit) {
    var key, cur, factor;

    var highLow = {/*see above*/};

    for (var i = 2; i < SatWaterMetric.length; i++) {
        if (myval < SatWaterMetric[i][unit]) {
            for (key in highLow) {
                highLow[key].low = SatWaterMetric[i - 2][key];
                highLow[key].high = SatWaterMetric[i - 1][key];
            }

            factor = (myval - highLow.T.low) / (highLow.T.high - highLow.T.low);

            for (key in highLow) {
                cur = highLow[key];

                // This is T
                if (!cur.magnitude) {
                    cur.result = myval;
                } else {
                    cur.result = (1 * cur.low) + (1 * factor * (cur.high - cur.low));
                }
            }
            break;
        }
    }

    for (key in highLow) {
        cur = highLow[key];
        $('#txt' + key.toLowerCase()).val(Math.round(cur.result * (cur.magnitude || 1)) / (cur.magnitude || 1));
    }
}

演示 jsFiddle


版本 2:此版本通过重构显示计算并将其直接分配给关联的 highLow 键并内联计算最终显示值,从而消除了前面示例中的冗余循环。

演示 jsFiddle

代码:

// Generates a result for display using the provided magnitude to 
// format the calculated value.
function calcFn(T, factor, low, high, magnitude) {
    var retVal = (1 * low) + (1 * factor * (high - low));

    return Math.round(retVal * (magnitude || 1)) / (magnitude || 1);
}

var highLow = {
    // Initializing T with a calc function that just returns the passed in value
    // This makes the calc/display loop much simpler
    T:    { calc:   function(T) { return T; }, 
            factor: function(T, low, high) { return (T - low) / (high - low); } },

    // All other metrics will use calcFn
    Psat: { magnitude:   100000, calc: calcFn },
    vf:   { magnitude: 10000000, calc: calcFn },
    vg:   { magnitude:   100000, calc: calcFn },
    hf:   { magnitude:    10000, calc: calcFn },
    hg:   { magnitude:      100, calc: calcFn },
    hfg:  { magnitude:      100, calc: calcFn }
};

// Note: Started loop at 2 to avoid undefined array values
function interpolate(myval, unit) {
    var key, cur, factor, result, high, low;

    for (var i = 2; i < SatWaterMetric.length; i++) {
        if (myval < SatWaterMetric[i][unit]) {
            // T is in slot 0
            factor = highLow.T.factor(myval, SatWaterMetric[i - 2].T, SatWaterMetric[i - 1].T);

            // Now we can simply loop through all metrics using the assigned calc function to 
            // generate a result for display.
            for(key in highLow) {
                cur    = highLow[key];
                low    = SatWaterMetric[i - 2][key];
                high   = SatWaterMetric[i - 1][key];
                result = cur.calc(myval, factor, low, high, cur.magnitude);

                $('#txt' + key.toLowerCase()).val(result);
            }

            break;
        }
    }
}
于 2013-09-05T20:25:25.480 回答