[英]How do I refactor these javascript if else conditional statements in my app?
我正在構建一個使用兩個滑塊的計算器,如下所示:
我有一系列存儲在這樣的對象中的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";
}
}
如您所見,我將處理幾乎無窮無盡的條件列表,以返回所選計划。 除了條件語句或案例語句之外,是否有任何方法可以簡化基於代碼的這些計划配置的存儲或選擇?
改用數組:
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;
}
}
好了,回到這個問題,我以為我會花兩分錢...
我會使用數組來壓縮您的數據存儲,因此不再需要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
}
不太干凈,但是它可以讓您盡早打破循環。
這些很容易通過其他類似的比較進行擴展。
您可以使用給定的val遍歷配置。 就像是
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;
}
}
您可以從中執行更通用的功能:
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
為對象,枚舉順序是不確定的(取決於實現),因此當它們的范圍不明確時,它可能會返回任何計划。
您可以做的一件事是(動態地,預先地)創建其值代表相應范圍的數組:
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"
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.