我們一起聊聊如何簡化多個 if 的判斷結構
多少算太多?
有些人認為數字就是一,你應該總是用至少一個三元運算符來代替任何單個 if 語句。我并不這樣認為,但我想強調一些擺脫常見的 if/else 意大利面條代碼的方法。
我相信很多開發人員很容易陷入 if/else 陷阱,不是因為其他解決方案的復雜性,而是因為它遵循這樣的自然語言模式:if 執行此操作, else 執行此操作。
等等,什么是三元運算符?
三元運算符與 if/else 并沒有革命性的區別,因為它們都是條件操作,但三元運算符會返回一個值,因此可以直接用于賦值。
const greaterThanFive = (8 > 5) ? 'yep' : 'nope';
console.log(greaterThanFive); // 'yep'
基本模式只是一個條件,如果為真則返回一個值,如果為假則返回另一個值。
(condition) ? isTruthy : isFalsy
IF/ELSE 的替代方案
讓我們從一個場景開始,逐步了解不同解決方案的示例。
我們將從用戶輸入中獲取顏色,并需要將它們轉換為一些預設的顏色代碼來匹配,以便我們可以更改背景顏色。因此,我們將檢查顏色名稱字符串,并在匹配時設置顏色代碼。
const setBackgroundColor = (colorName) => {
let colorCode = '';
if(colorName === 'blue') {
colorCode = '#2196F3';
} else if(colorName === 'green') {
colorCode = '#4CAF50';
} else if(colorName === 'orange') {
colorCode = '#FF9800';
} else if(colorName === 'pink') {
colorCode = '#E91E63';
} else {
colorCode = '#F44336';
};
document.body.style.backgroundColor = colorCode;
};
這個 if/else 就完成了工作。但是我們背負著大量重復邏輯比較 colorName 和重復賦值 colorCode。
Switch ?
現在我們可以更恰當地將其更改為 switch 語句。它更符合我們正在嘗試做的事情的概念;我們有幾種想要匹配的字符串情況,如果沒有一種情況匹配,則有一個默認值。
const setBackgroundColor = (colorName) => {
let colorCode = '';
switch(colorName) {
case 'blue':
colorCode = '#2196F3';
break;
case 'green':
colorCode = '#4CAF50';
break;
case 'orange':
colorCode = '#FF9800';
break;
case 'pink':
colorCode = '#E91E63';
break;
default:
colorCode = '#f44336';
};
document.body.style.backgroundColor = colorCode;
};
但是 switch 仍然帶有大量我們可以不需要的樣板文件和重復代碼。
Lookup Table 查找表
那么我們真正想要實現什么目標呢?我們需要將十六進制顏色代碼分配給顏色名稱,因此讓我們創建一個將顏色名稱作為鍵、將顏色代碼作為值的對象。然后我們可以使用 object[key] 通過顏色名稱查找顏色代碼。我們需要一個默認值,因此如果沒有找到鍵,則返回默認值的短三元運算符將在創建對象的默認部分時執行此操作。
const colorCodes = {
'blue' : '#2196F3',
'green' : '#4CAF50',
'orange' : '#FF9800',
'pink' : '#E91E63',
'default': '#F44336'
};
const setBackgroundColor = (colorName) => {
document.body.style.backgroundColor = colorCodes[colorName]
? colorCodes[colorName]
: colorCodes['default'];
};
現在我們有了一個查找表,可以整齊地列出我們的輸入和可能的輸出。
這并不是奇跡般地減少了“代碼行數”(LOC)(我們從 15 行減少到 20 行,再減少到 12 行)。事實上,其中一些解決方案可能會增加您的 LOC,但我們提高了可維護性、易讀性,并且實際上通過僅對默認回退進行一次邏輯檢查來降低復雜性。
數據的交易邏輯
在 if/else 或 switch 上使用查找表的最重要成就是我們將比較邏輯的多個實例轉換為數據。代碼更具表現力;它將邏輯顯示為操作。代碼更具可測試性;邏輯被減少了。而且我們的比較更容易維護;它們被合并為純數據。
讓我們將五個比較邏輯運算減少為一個,并將我們的值轉換為數據。
場景:我們需要將成績百分比轉換為對應的字母成績。
if/else 很簡單;我們從上到下檢查成績是否高于或等于匹配字母成績所需的成績。
const getLetterGrade = (gradeAsPercent) => {
if(gradeAsPercent >= 90) {
return "A";
} else if(gradeAsPercent >= 80) {
return "B";
} else if(gradeAsPercent >= 70) {
return "C";
} else if(gradeAsPercent >= 60) {
return "D";
} else {
return "F"
};
};
但我們一遍又一遍地重復相同的邏輯運算。
因此,讓我們將數據提取到一個數組中(以保留順序)并將每個等級的可能性表示為一個對象?,F在我們只需對對象進行一次 >= 比較,并找到數組中第一個匹配的對象。
const gradeChart = [
{minpercent: 90, letter: 'A'},
{minpercent: 80, letter: 'B'},
{minpercent: 70, letter: 'C'},
{minpercent: 60, letter: 'D'},
{minpercent: 0, letter: 'F'}
];
const getLetterGrade = (gradeAsPercent) => {
const grade = gradeChart.find(
(grade) => gradeAsPercent >= grade.minpercent
);
return grade.letter;
};
開始將您的比較想象為數據
當你需要比較或“檢查”數值時,很自然地會想到 if/else,這樣你就可以用語言逐步解決問題。但下一次,請試著思考如何將您的值表示為數據,并通過簡化邏輯來解釋這些數據。
您的代碼最終將變得更具可讀性、可維護性和目的性,并且其所代表的概念清晰分離。
原文:https://dreith.com/blog/theres-such-a-thing-as-using-too-many-ifs/