逻辑上相似的代码的循环复杂性

Jam*_*ice 3 javascript cyclomatic-complexity

考虑以下三个函数,它们都以相同的方式运行,使用不同的代码来实现相同的事情(示例是用JavaScript编写的,我对应用于JavaScript的答案特别感兴趣,但这个问题可能真的适用于任何具有类似结构的语言):

// Random number from 0-9
var x = Math.floor(Math.random() * 10);

// JSHint reports a cyclomatic complexity of 3
function a() {
    if (x === 0) {
        return "First";
    } else if (x === 1 || x === 2) {
        return "Second"; 
    }
    return "Third";
}

// JSHint reports a cyclomatic complexity of 4
function b() {
    switch (x) {
    case 0:
        return "First";
    case 1:
    case 2:
        return "Second";
    default:
        return "Third";
    }
}

// JSHint reports a cyclomatic complexity of 1
function c() {
    return x === 0 ? "First" : x === 1 || x === 2 ? "Second" : "Third";
}

// All three functions return the same value
console.log(a(), b(), c());
Run Code Online (Sandbox Code Playgroud)

所述JSComplexity工具报告所有三个功能具有的4复杂性,这意味着||运营商都作为独立的分支处理,因为是落空case语句.JSHint似乎并不关心||运算符,但它确实case以相同的方式处理直通语句.它似乎让条件运算符完全错误.

在计算圈复杂度时,是否应将直通case语句和逻辑"或"运算符视为独立分支?三元条件怎么样(我相信这更简单,在这种情况下JSHint显然是错误的)?上述所有三个函数是否都具有相同的圈复杂度?

Xop*_*ter 7

循环复杂性是通过代码的线性独立路径的数量.虽然坠落case是空洞的,但我相信这是一条不同的道路.那么问题是是否||引入了新的分支?

我只是大声思考,在这里,但我认为因为JavaScript对条件进行短路评估,我们确实从分离得到了两个分支.例如,您的a功能相当于:

function a() {
    if (x === 0) {
        return "First";
    } else if (x === 1) {
        return "Second"; 
    } else if (x === 2) {
        return "Second";
    } else {
       return "Third";
    }
}
Run Code Online (Sandbox Code Playgroud)

...有4个分支,即使其中两个执行相同的功能.(即,边缘上的线性独立性,而不是顶点.)但是,如果JS没有进行短路评估,我倾向于考虑x === 1 || x === 2只调用一个分支.

所以,为了回答你的问题,我认为你的所有三个函数应该具有相同的圈复杂度:4.