0

次のような 2 つのスライダーを使用する電卓を作成しています。

ここに画像の説明を入力

次のようなオブジェクトに格納されている一連の CPU および RAM データがあります。

var CloudPlans = {
   small: {

        id: 'small',

        from: {
            cpu: 1,
            ram: 1
        },

        to: {
            cpu: 2,
            ram: 2
        },

        price: {
            linux: 3490,
            windows: 4190
        }
    },

    medium:  {

        id: 'medium',

        from: {
            cpu: 2,
            ram: 2
        },

        to: {
            cpu: 4,
            ram: 4
        },

        price: {
            linux: 5600,
            windows: 6300
        }

    },

    large: {

        id: 'large',

        from: {
            cpu: 4,
            ram: 4
        },

        to: {
            cpu: 6,
            ram: 8
        },

        price: {
            linux: 9500,
            windows: 10200
        }

    },

           [...more configs here]

}

スライダーの位置と値に基づいて、ユーザーが選択したプランを確認し、コンポーネントの価格を計算する必要があります。価格帯をチェックする関数は次のとおりです。

    checkPlaninRange: function(cpuVal, ramVal) {
        if(cpuVal >= CloudPlan.small.from.cpu && cpuVal <= CloudPlan.small.to.cpu ) {
            return "small";
        } else if (ramVal >= CloudPlan.small.from.cpu && ramVal <= CloudPlan.small.to.cpu) {
            return "small";
        }
    }

ご覧のとおり、選択したプランを返す条件のほぼ無限のリストを処理します。条件またはケース ステートメント以外のコードに基づいて、これらのプラン構成の保存または選択を簡素化する方法はありますか?

4

5 に答える 5

3

代わりに配列を使用します。

var CloudPlans = [
   {
        id: 'small',
        from: {
            cpu: 1,
            ram: 1
        },
        to: {
            cpu: 2,
            ram: 2
        },
        price: {
            linux: 3490,
            windows: 4190
        }
    },

    {
        id: 'medium',
        from: {
            cpu: 2,
            ram: 2
        },
        to: {
            cpu: 4,
            ram: 4
        },
        price: {
            linux: 5600,
            windows: 6300
        }
    },
    {
        id: 'large',
        from: {
            cpu: 4,
            ram: 4
        },
        to: {
            cpu: 6,
            ram: 8
        },
        price: {
            linux: 9500,
            windows: 10200
        }
    },
           //[...more configs here]
}

これで、次のように単純に繰り返すことができますCloudPlans:

for(int planIdx = 0; planIdx < CloudPlans.length; ++planIdx) {
    var plan = CloudPlan[planIdx];
    if(cpuVal >= plan.from.cpu && cpuVal <= plan.to.cpu  || 
       ramVal >= plan.from.ram && ramVal <= plan.to.ram) {
           return plan.id;
    }
}
于 2012-11-12T18:56:49.577 に答える
2

さて、この質問に戻ると、私は 2 セントを投じようと思いました...

配列を使用してデータ ストレージを少し圧縮すると、値が不要になりminます。

var CloudPlans = [
   {    id: 'small',
        maxcpu: 2,
        maxram: 2,
        price: {
            linux: 3490,
            windows: 4190
        }
    }, {id: 'medium',
        maxcpu: 4,
        maxram: 4,
        price: {
            linux: 5600,
            windows: 6300
        }
    }, {id: 'large',
        maxcpu: 6,
        maxram: 8,
        price: {
            linux: 9500,
            windows: 10200
        }
    }, 
    // etc
].reverse(); // reverse it so the highest plan is first

に注意して.reverse()ください。上から順に比較していきます。


次に、reduce 関数を使用します。

checkPlaninRange: function(cpuVal, ramVal) {
    return CloudPlans.reduce(function(plan, compare) {
        return cpuVal <= compare.maxcpu && 
               ramVal <= compare.maxram    ? compare : plan;
    }).id; // remove .id to return the entire object
}

または、もう少し効率的なものが必要な場合forは、同じ方法でループを使用します。

checkPlaninRange: function(cpuVal, ramVal) {
    var plan = CloudPlans[0];
    for (var i = 1; i < CloudPlans.length; i++) {
        if (cpuVal <= CloudPlans[i].maxcpu && 
            ramVal <= CloudPlans[i].maxram    ) {
            plan = CloudPlans[i];
        } else break;
    }
    return plan.id; // remove .id to return the entire object
}

それほどきれいではありませんが、ループを早期に中断できます。


これらは、同様の比較を追加して簡単に拡張できます。

于 2012-11-12T20:41:06.843 に答える
1

これからより一般的な関数を作成できます。

function check(plan, values) {
    for (var prop in values)
        if (plan.from[prop] <= values[prop] && plan.to[prop] >= values[prop])
             return true; // if only one property is met
    return false;
}
// yet I guess this is what you want:
function check(plan, values) {
    for (var prop in values)
        if (plan.from[prop] > values[prop] || plan.to[prop] < values[prop])
             return false; // if only one property is not met
    return true; // if all properties are met
}

checkPlaninRangeメソッドは次のようになります。

checkSmallRange: function(cpuVal, ramVal) {
    if ( check(CloudPlan.small, {cpu:cpuVal, ram:ramVal}) )
        return "small";
}

もちろん、それを使用してクラウド プランをループすることもできます。

getPossiblePlans: function(cpuVal, ramVal) {
    var plans = []
    for (var id in CloudPlans)
        if ( check(CloudPlans[id], {cpu:cpuVal, ram:ramVal}) )
            plans.push(id);
    return plans;
}

@Tomasz Nurkiewiczが述べたように、ここではループ順序が定義された配列の方が適しています。オブジェクトでCloudPlansあるため、列挙の順序は定義されていない (実装に依存する) ため、範囲が明確でない場合は任意のプランを返す可能性があります。

于 2012-11-12T19:02:24.733 に答える
1

指定された値で構成をループできます。何かのようなもの

var planFrom, planTo, cpuInRange, ramInRange;

for (var plan in CloudPlans) {
   planFrom = plan.from;
   planTo = plan.to;
   cpuInRange = cpuVal >= planFrom.cpu && cpuVal < planTo.cpu;  
   ramInRange = ramVal >= plamFrom.ram...; 
   if (cpuInRange || ramInRange) {
      return plan.id; 
   } 
}
于 2012-11-12T18:56:24.597 に答える
-2

簡単にできることの1つは、(動的に、事前に)値がそれぞれの範囲を表す配列を作成することです。

var cpu = ["small", "small", "medium", "medium", "medium", "large"];
var ram = ["small", "medium", "medium", "medium", "large"];

このように使用します:

function checkPlaninRange(cpuVal, ramVal) {
    return cpu[Math.floor(cpuVal)] || "large";
}

checkPlaninRange(4.2); // "medium"
于 2012-11-12T19:14:10.570 に答える