我怎样才能重构这一堆if语句?

时间:2016-09-25 12:53:34

标签: javascript if-statement

想象一下,我有一个名为 incomingValue 的变量,我从API中获取了一个数字作为它的值。这些值在0到1之间,我正在设置另外两个变量,具体取决于这个值,使用if if语句,如下所示。

var incomingValue; // Set by an API
var setValueName;
var setValueIcon;
if (incomingValue < 0.10 ) { 
  setValueName = 'something'; 
  setValueIcon = 'something.png' 
}
if (incomingValue > 0.09 && incomingValue < 0.20 ) { 
  setValueName = 'somethingElse'; 
  setValueIcon = 'somethingElse.png';
}

在实际实现中,我有大约10个if语句检查特定时间间隔直到 1 e.g。如果它大于0.10但小于0.16,则执行此操作。依此类推。

作为一名JavaScript初学者,感觉即使完成工作,这也不是正确的做事方式。我将如何重构此代码?

更新:根据要求,我正在添加原始代码中使用的全套间隔。我之前没有包括完整列表,因为间隔不遵循某种模式。

  • 0至0.09
  • 0.09至0.20
  • 0.20至0.38
  • 0.38至0.48
  • 0.48至0.52
  • 0.52至0.62
  • 0.61至0.80
  • 0.80至1

4 个答案:

答案 0 :(得分:12)

记住单一责任原则。把代码带到一个单独的函数,如:

function determineNameAndIcon(incomingValue) {
  if (incomingValue < 0.10) { 
    return { 
      name: "something",
      icon: "something.png"
    };
  }
  if (incomingValue < 0.20) { 
    return {
      name: "somethingElse",
      icon: "somethingElse.png"
    };
  }
  // etc
  return {
    name: "somethingDefault",
    icon: "somethingDefault.png"
  };
}

// ...

var incomingValue; // Set by an API
const {
  name: setValueName,
  icon: setValueIcon
} = determineNameAndIcon(incomingValue);

请注意,determineNameAndIcon仍然是一个包含重复部分的非常长的函数。这可以进一步重构为数据驱动版本:

const nameAndIconList = [
  {
    maxValue: 0.10,
    name: "something",
    icon: "something.png"
  },
  {
    maxValue: 0.20,
    name: "somethingElse",
    icon: "somethingElse.png"
  },
  // ...
];

const nameAndIconDefault = {
  name: "somethingDefault",
  icon: "somethingDefault.png"
};

function determineNameAndIcon(incomingValue) {
  for (let item of nameAndIconList) {
    if (incomingValue < item.maxValue) {
      return item;
    }
  }
  return nameAndIconDefault;
}

答案 1 :(得分:2)

function findValue(incomingValue){

    var itemValues = [
      [.06, "valueName", "valueIcon"],  
      [.08, "valueName", "valueIcon"],
      [.09, "valueName", "valueIcon"],
      [.1, "valueName", "valueIcon"],

    ]


  var foundValues = itemValues.
        filter(v=>v[0] >= incomingValue)
        .sort();

  if(foundValues.length == 0){
     throw "incoming value not found."
  } 
  return foundValues[0];
}

let value = findValue(.079);

console.log( value );

这假设您希望范围的最低部分是所选的部分(如果您希望它最高,则反转排序)。

答案 2 :(得分:1)

使用数组的解决方案,您可以在其中设置结果的范围:

&#13;
&#13;
var categories = [{something: [0, 0.1]}, 
                  {somethingElse: [0.1, 0.2]}, 
                  {somethingElse2: [0.2, 0.3]}, 
                  {anotherSomething: [0.3, 1]}];

function res(number){ return Object.keys(categories.filter(function(elem) {
  var key = elem[Object.keys(elem)];
  return number >= key[0] && number < key[1]
})[0])[0]};

var incomingValue = 0.12;

var setValueName = res(incomingValue);
var setValueIcon = res(incomingValue) + ".png";
console.log(setValueName, setValueIcon);
&#13;
&#13;
&#13;

答案 3 :(得分:0)

Mb我会像这样重构这段代码,但它并不是真正的标准模式:

var incomingValue=0.08; // Set by an API
var setValueName;
var setValueIcon;

switch(true) {
    case incomingValue < 0.10 :
        setValueName = "something"; 
        setValueIcon ="something.png";
        alert("Hello World !");
        break;
    case incomingValue > 0.09 && incomingValue < 0.20 :
        setValueName = "somethingElse"; 
        setValueIcon ="somethingElse.png";
        alert("Hello !");
        break;
    default :
        alert("Adele !");
        break;
}

凡人将使用if ...... else if ......这样的条件:

var incomingValue; // Set by an API
var setValueName;
var setValueIcon;
if (incomingValue < 0.10 ) { 
    setValueName = "something"; 
    setValueIcon ="something.png" 
} **else** if (incomingValue > 0.09 && incomingValue < 0.20 ) { 
    setValueName = "somethingElse"; 
    setValueIcon ="somethingElse.png" 
}

但我不喜欢这样......我的意见:)。