1. 程式人生 > >其實我們可以少寫點if else和switch

其實我們可以少寫點if else和switch

三目運算 而是 不同 es6 con 業務 spring 代碼 查找

前言

作為搬磚在第一線的底層工人,業務場景從來是沒有做不到只有想不到的復雜。

不過他強任他強,if-else全搞定,搬就完了。但是隨著業務叠代或者項目交接,自己在看自己或者別人的if代碼的時候,心情就不再表述了,各自深有體會。所以我們一起看看if還能怎麽寫

最基本if-else

假設有這麽個場景,不同情況下打印不同值。

因為涉及到的條件太多,就不提三目運算之類優化了。

if (a == 1) {

console.log(‘a1‘)

} else if (a == 2) {

console.log(‘b2‘)

} else if (a == 3) {

console.log(‘c3‘)

} else if (a == 4) {

console.log(‘d4‘)

}

/ n..... /

現在還算能看,因為邏輯簡單,如果邏輯復雜,叠代多個版本之後,你還敢動嗎。

每動一下就戰戰兢兢,誰知道哪裏會遺漏。

那麽換種方式呢

switch-case

這樣稍微清晰那麽一點,差別好像沒什麽差別:

switch(a){

case 1:

console.log(‘a1‘);

break;

/ 省略。。。 /

case 40:

console.log(‘a40‘);

break;

}

分離配置信息與執行動作

object映射

定義一個object作為配置對象來存放不同狀態,通過鏈表查找

const statusMap = {

1:()=>{

console.log(‘a1‘)

},

2:()=>{

console.log(‘b2‘)

}

/ n.... /

}

// 執行

let a = 1

statusMap[a || 1]()

這樣比較清晰,將條件配置與具體執行分離。如果要增加其他狀態,只修改配置對象即可。

數組映射

當然在某些狀態下可以使用數組,來做這個配置對象。

// 這裏就涉及其他優化了,例如將執行函數抽離出來,大家不要關註func的內容就好。

// 它就是個function,內容很復雜

const statusArr = [function(){

console.log(1)

},

function () {

console.log(2)

},]

// 執行

let a = 1

statusArr[a || 1]()

數組的要求更高一點,如果是其他key,例如字符串,那麽數組就不能滿足需求了

升級版:不同key相同value

這樣看起來好一點了,那麽需求又有變動了,

前面是每種處理方式都不同,下面有幾種情況下處理函數相同的,例如1-39的時候,調用a,40之後調用b,如果我們繼續來用映射的方式來處理。

function f1 (){

console.log(1)

}

function f2 (){

console.log(2)

}

const statusMap={

1:f1,

2:f1,

3:f1,

4:f1,

//省略

40:f2

}

let a = 2

statusMap[a]()

這樣當然也可以,不過重復寫那麽多f1,代碼看起來不夠簡潔。

開始重構之前我們先捋一下思路,無非是想把多個key合並起來,對應一個value。也就是說我們的鍵值不是字符串而是個數組,object顯然只支持字符串,那麽可以將這麽多key合並成一個:‘1,2,3,4,..,9‘。

但是查找的時候有點問題了,我們的參數肯定不能完全匹配。

接著走下去,是不是做個遍歷加個判斷,包含在子集內的都算匹配,那麽代碼看起來就是下面這個樣子。

// 將鍵值key設置為一個拼接之後的字符串

const statusMap = {

‘1,2,3,4,5‘: f1,

//省略

40: f2

}

// 獲取所有的鍵值,待會遍歷用

const keys = Object.keys(statusMap),

len = keys.length

// 遍歷獲取對應的值

const getVal=(param=‘‘)=>{

// 用for循環的原因在於匹配之後就不需要繼續遍歷

for (let i = 0; i < len; i++) {

const key = keys[i],

val = statusMap[key]

// 這裏用什麽來判斷就隨便了,兩個字符串都有。

if (key.includes(param)) {

return val

}

}

}

let a = 2,

handle = getVal(a)

handle() // 1

但是這樣來看,增加了個遍歷的過程,而且是拼接字符串,萬一哪天傳了個逗號進來,會得到了預料之外的結果。

map

es6有個新的數據結構Map,支持任意數據結構作為鍵值。如果用Map可能更清晰一點。

/**

  • map鍵值索引的是引用地址,

  • 如果是下面這樣的寫法不好意思,永遠得不到值

  • map1.set([1,4,5],‘引用地址‘)

  • map1.get([1,4,5]) //輸出為undefined

  • 就像直接訪問

  • map1.get([1,2,3,4,5]) //同樣為undefined

*/

const map1 = new Map()

const statusArr = [1,2,3,4,5]

map1.set(statusArr,f1)

// 預設默認值,因為不能直接遍歷

let handle = function(){}

const getVal = (param = ‘‘) => {

for (let value of map1.entries()) {

console.log(JSON.stringify(value))

if (value[0].includes(param)){

console.log(value)

// 不能跳出 只能處理了

handle = value[1]

}

}

}

const a = 2

getVal(a)

handle()

個人而言雖然這樣減少了重復代碼,但是又增加了一步匹配值的操作,優劣就見仁見智吧。

雙數組

肯定有部分人就是不想做遍歷的操作,既然一個數組不能滿足,那麽兩個數組呢。

// 鍵值數組和value 保持對應關系

const keyArr = [‘1,2,3,4,5‘,‘40‘]

const valArr = [f1,f2]

const getVal = (param = ‘‘)=>{

// 查找參數對應的下標

let index = keyArr.findIndex((it)=>{

return it.includes(param)

})

// 獲取對應值

return valArr[index]

}

let a = 2,

handle = getVal(a)

handle()

利用數組提供的下標,將key和value對應起來,進而獲取想要的值。

這裏一直沒有達到我最初的目的,即鍵裏面重復的數組,可以不通過多余操作匹配到,上面不管怎麽樣都進行了處理,這不是懶人的想要的。
如果想學習Java工程化、高性能及分布式、深入淺出。微服務、Spring,MyBatis,Netty源碼分析的朋友可以加我的Java高級交流:787707172,群裏有阿裏大牛直播講解技術,以及Java大型互聯網技術的視頻免費分享給大家。

其實我們可以少寫點if else和switch