如何将风险矩阵转换为数据结构?

时间:2018-02-22 03:49:02

标签: javascript maintainability

我正在编写一个简单的应用程序,它会考虑风险发生的可能性及其结果的严重程度,并将其转化为基于风险矩阵的风险程度的评级。

我目前的解决方案是将可能性和结果转换为1-5,将它们相乘,然后在一堆if / else语句中使用结果来获得风险评级。我的问题是范围重叠,我必须单独处理这些情况,我觉得这有点像一个警察。

var likelihoods = {         
    "Rare" : 1,
    "Unlikely" : 2,
    "Possible" : 3,
    "Likely" : 4,
    "Almost Certain" : 5,
};

var consequences = { 
    "Minor" : 1,
    "Moderate" : 2,
    "Major" : 3,
    "Severe" : 4,
    "Extreme" : 5,
};

var likelihood = likelihoods[item.likelihood];  
var consequence = consequences[item.consequence];  

var riskVal= likelihood * consequence;

if (likelihood == 2 && consequence == 2) { riskRating = 1 }
else if (likelihood == 1 && consequence == 5) { riskRating = 3 }
else if (likelihood == 2 && consequence == 5) { riskRating = 4 }

else if (riskVal <= 3) { riskRating = 1 } //Low risk 
else if (riskVal <= 6) { riskRating = 2 } //Medium risk
else if (riskVal <= 12) { riskRating = 3 } //High risk
else { riskRating = 4 } //Critical risk

这样做更干净的方法是什么?

1 个答案:

答案 0 :(得分:2)

我认为最好将此作为自我记录。所以实际上包括源代码中的表格对我来说非常有帮助。为此,我将编写一个(希望是通用的)函数来解析这样的表并返回一个接受行和列并返回匹配值的函数。也许是这样的:

const lookup = (tbl) => {
  const allRows = tbl.split('\n')
        .filter(row => row.length && !row.startsWith('|---'))
  const colNames = allRows[0].split(/\|/).map(s => s.trim())
        .filter(s => s.length > 0)
  const rows = allRows.slice(1).map(r => r.split(/\|/)
        .map(s => s.trim()).filter(s => s.length > 1))
  const table = rows.reduce((table, row) => {
    table[row[0]] = row.slice(1).reduce((r, col, idx) => {
      r[colNames[idx]] = col;
      return r
    }, {})
    return table
  }, {});
  return (row, col) => (table[row] || {})[col]
}

var riskVal = lookup(`
                   | Minor  | Moderate | Major    | Severe   | Extreme  |
  |----------------|--------|----------|----------|----------|----------| 
  | Rare           | Low    | Low      | Low      | Medium   | High     | 
  | Unlikely       | Low    | Low      | Medium   | High     | High     |
  | Possible       | Low    | Medium   | High     | High     | Critical |  
  | Likely         | Medium | High     | High     | Critical | Critical |   
  | Almost Certain | Medium | High     | Critical | Critical | Critical |
`)

console.log(riskVal('Possible', 'Severe')) //=> 'High'
console.log(riskVal('Almost Certain', 'Major')) //=> 'Critical
console.log(riskVal('Unlikely', 'Extreme')) //=> 'High
console.log(riskVal('Rare', 'Minor')) //=> 'Low'
console.log(riskVal('Possible', 'Moderate')) //=> 'Medium'

显然,如果你想要输入或输出的数值,你可以只是切换表,虽然你可能不得不在你去的时候解析一些字符串(或字符串化一些数字。)

请注意lookup是通用的。如果如图所示构造表,那么行或列标题中的内容无关紧要,返回的函数应该产生适当的单元格值。当然,没有重复的行或列标题,但这似乎是一个合理的限制。

另请注意,我已将代码快速转换回表格。那里可能有一两个错误。不要指望这个特定的表格是准确的。