編程技巧:嘗試不用 If 語句編程

Coding Tip: Try to Code Without If-statements

ifcode.png

如今開始,請嘗試儘可能避免使用if語句來實現咱們的業務編程

你可能會疑問不使用if有什麼好處?額~,可能也沒啥很明顯的好處,就是換種思考方式來解決問題。if-else並無錯,但在某些狀況下大量的if-else可能會下降代碼可讀性。下面會列舉一些實例帶你感覺其中的奧妙。小程序

Challenge #1: 統計數值數組中共有多少個奇數

已知一個整數類型數組,統計該數組中奇數的個數數組

const arrayOfIntegers = [1, 4, 5, 9, 0, -1, 5];

if實現瀏覽器

let counter = 0;
arrayOfIntegers.forEach((integer) => {
  const remainder = Math.abs(integer % 2);
  if (remainder === 1) {
    counter++;
  }
});
console.log(counter);

非if實現編程語言

let counter = 0;
arrayOfIntegers.forEach((integer) => {
  const remainder = Math.abs(integer % 2);
  // 偶數除2的餘數爲零,奇數的餘數爲一
  counter += remainder;
});
console.log(counter);

記: 上述兩個例子,forEach是會改變原數組的,方法是可變的,違背了當下所提倡的函數式編程immutable理念,不用在乎,不是本文關注點。兩個例子比較而言,if語句的實現可能更具兼容性,能夠適應於數組元素是小數的狀況。若數組元素爲浮點類型,第二個例子就沒法正常使用。函數式編程

Challenge #2: 判斷一個日期是週末仍是工做日

實現一個函數,日期對象 new Date()做爲輸入,根據不一樣日期返回當天是工做日仍是週末函數

if實現spa

const weekendOrWeekday = inputDate => {
  const day = inputDate.getDay();
  if (day === 0 || day === 6) {
    return 'weekend';
  }

  return 'weekday';
  // Or, for ternary fans:
  // return (day === 0 || day === 6) ? 'weekend' : 'weekday';
};
console.log(weekendOrWeekday(new Date()));

非if實現.net

const weekendOrWeekday = (inputDate) => {
  const day = inputDate.getDay();
  return weekendOrWeekday.labels[day] ||
         weekendOrWeekday.labels['default'];
};
weekendOrWeekday.labels = {
  0: 'weekend',
  6: 'weekend',
  default: 'weekday'
};
console.log(weekendOrWeekday(new Date()));

有沒有注意到,if語句中的數字表明哪天是週末,斷定條件分佈的較爲零散,咱們須要作的是將數字和週末或工做日類型對應起來,如例子2,可使用一個對象或者map來存儲對應關係。翻譯

上述兩個例子對比,能夠明顯看出非if代碼實現具備更好的可讀性和擴展性

Challenge #3: The doubler function (here be dragons),翻譯不出來~尬~

實現一個doubler函數,根據輸入不一樣,作以下處理:

  1. 若輸入是number類型, 作翻倍處理(5 => 10, -10 => -20)
  2. 若輸入是string類型,重複每一個字符('hello' => 'hheelloo')
  3. 若輸入是function類型,調用執行兩次函數
  4. 若輸入是array類型,對數組的每一個元素作doubler處理
  5. 若輸入是object類型,對對象的每一個屬性作doubler處理

switch實現

const doubler = (input) => {
  switch (typeof input) {
    case 'number':
      return input + input;
    case 'string':
      return input
        .split('')
        .map(letter => letter + letter)
        .join('');
    case 'object':
      Object.keys(input)
            .map(key => (input[key] = doubler(input[key])));
      return input;
    case 'function':
      input();
      input();
  }
};
console.log(doubler(-10));
console.log(doubler('hey'));
console.log(doubler([5, 'hello']));
console.log(doubler({ a: 5, b: 'hello' }));
console.log(
  doubler(function() {
    console.log('call-me');
  }),
);

switch實現

const doubler = (input) => {
  return doubler.operationsByType[typeof input](input);
};
doubler.operationsByType = {
  number: (input) => input + input,
  string: (input) =>
    input
      .split('')
      .map((letter) => letter + letter)
      .join(''),
  function: (input) => {
    input();
    input();
  },
  object: (input) => {
    Object.keys(input)
          .map((key) => (input[key] = doubler(input[key])));
    return input;
  },
};
console.log(doubler(-10));
console.log(doubler('hey'));
console.log(doubler([5, 'hello']));
console.log(doubler({ a: 5, b: 'hello' }));
console.log(
  doubler(function() {
    console.log('call-me');
  }),
);

和Challenge #2相似,將條件值聚合在一塊兒作統一處理。

總結

if-else的判斷條件較多時,將條件作集中處理(用object存儲其對應關係--條件作key,處理作value)。好處是增刪某個條件變得容易,代碼更加可讀,提倡使用key-value對應來取代一部分的if-else的條件判斷。

【開發環境推薦】 Cloud Studio 是基於瀏覽器的集成式開發環境,支持絕大部分編程語言,包括 HTML五、PHP、Python、Java、Ruby、C/C++、.NET 小程序等等,無需下載安裝程序,一鍵切換開發環境。 Cloud Studio提供了完整的 Linux 環境,而且支持自定義域名指向,動態計算資源調整,能夠完成各類應用的開發編譯與部署。
相關文章
相關標籤/搜索