2015-12-02 65 views
2

如何让这些javascript语句看起来更具可读性。可以使用函数库ramda.js来使代码看起来更好吗?如何让这段代码更具功能性和可读性?

var getTextSpace = function(len) 
    { 
      var tlength; 
      if (len >= 1 && len <= 4) { 
       tlength = 10; 
      } else if (len === 5) { 
       tlength = 14; 
      } else if (len === 6) { 
       tlength = 16; 
      } else if (len === 7) { 
       tlength = 18; 
      } else if (len >= 8 && len <= 10) { 
       tlength = 20; 
      } else if (len === 11) { 
       tlength = 22; 
      } else if (len === 12) { 
       tlength = 24; 
      } else if (len >= 13 && len <= 15) { 
       tlength = 26; 
      } else if (len === 16) { 
       tlength = 28; 
      } else if (len >= 17 && len <= 20) { 
       tlength = 32; 
      } else if (len >= 21 && len <= 34) { 
       tlength = tlength * 2; 
      } else if (len >= 35 && len <= 80) { 
       tlength = Math.round((len + len/100 * 50)); 
      } 
      else { 
       tlength = Math.round((len + len/100 * 30)); 
      } 
     return tlength; 
    }; 

在此先感谢您。

也许有可能做一些事情可以做到这一点?

value 
    .between(2,20).then(20) 
    .between(21,22).then(0) 
    .greater(25).then(25)) 
    .less(30).then(function(value) {return value * 20)}) 
+4

[codereview.se]? – vaultah

+1

我投票结束这个问题作为题外话,因为它可能属于http://codereview.stackexchange.com/ – Andy

+0

当然,但你不会得到任何答案。但我会尽力回到这里。 – Ant

回答

6

Ramda可能会有点帮助。但主要的是以可读的方式构建你的范围。下面的代码假设输入值是整数,并且您不需要测试其他数字类型。这些都可以完成,但是这里需要比简单的between更复杂的东西。您需要多种功能或配置方法来确定每个开始和结束是包含性的还是独占性的。

var getTextSpace = (function() { 
    // :: (Int, Int) -> (Int -> Bool) 
    var between = (begin, end) => R.both(R.gte(R.__, begin), R.lt(R.__, end)); 
    return R.cond([ 
    [between(1, 5), R.always(10)], 
    [between(5, 6), R.always(14)], 
    [between(6, 7), R.always(16)], 
    [between(7, 8), R.always(18)], 
    [between(8, 11), R.always(20)], 
    [between(11, 12), R.always(22)], 
    [between(12, 13), R.always(24)], 
    [between(13, 16), R.always(26)], 
    [between(16, 17), R.always(28)], 
    [between(17, 21), R.always(32)], 
    [between(21, 35), R.multiply(2)], // assuming original was typo 
    [between(35, 80), len => Math.round(len + len/100 * 50)], 
    [R.T, len => Math.round(len + len/100 * 30)] 
    ]); 
}()); 

(似乎有错误在原来的情况:

 } else if (len >= 21 && len <= 34) { 
      tlength = tlength * 2; 

我假设意味着

 } else if (len >= 21 && len <= 34) { 
      tlength = len * 2; 

,我在这里编码的等价物)

你可以看到这在Ramda REPL的行动。

+0

感谢您的ramda实施,并找到Bug – Ant

0

也许switch是一种替代方案。有一个帖子退出了类似的话题。

看起来正确here

1

您可以使用switch语句来避免所有if语句。

此外,如果LEN始终是一个整数,你可以把tlengths在一个数组,其中索引LEN的值相匹配:

var getTextSpace = function(len) { 

var tlengthArray = [10,10,10,10,14,16,18,20,20,20,22,24,26,26,26,28,32,32,32,32, len*2, Math.round((len + len/100 * 50)), Math.round((len + len/100 * 50))]; 

var tlength; 

if (len >= 1 && len <=20) { 
    tlength = tlengthArray[len-1]; 
} 
else if (len >= 21 && len <= 34) { 
    tlength = tlengthArray[20]; 
} 
else if (len >= 35 && len <= 80) { 
    tlength = tlengthArray[21]; 
} 
else { 
    tlength = tlengthArray[22]; 
} 

return tlength; 

} 
+0

maybecould是容易做到somehing到能够做到: 值 .between(2,20)。然后(20) .between(21,22)。然后(0) .greater(25)。然后(25)) .less(30).then(function(value){return value * 20)}) .... ) – Ant

+0

对不起,不知道你的意思。 – digglemister

+0

我更新了问题 – Ant

2

function getTextSpace(len) { 
 
    // If len falls within a range then return that length 
 
    var map = [ 
 
    [1, 4, 10], 
 
    [5, 5, 14], 
 
    [6, 6, 16], 
 
    [7, 7, 18], 
 
    [8, 10, 20], 
 
    [11, 11, 22], 
 
    [12, 12, 24], 
 
    [13, 15, 26], 
 
    [16, 16, 28], 
 
    [17, 20, 32] 
 
    ]; 
 

 

 
    for (var i = 0; i < map.length; i++) { 
 
    var range = map[i]; 
 
    if (len >= range[0] && len <= range[1]) { 
 
     return range[2]; 
 
    } 
 
    } 
 

 
    // We didn't find a range so return return calculation 
 
    // for the following ranges. 
 
    if (len >= 21 && len <= 34) { 
 
    return len * 2; 
 
    } else if (len >= 35 && len <= 80) { 
 
    return Math.round((len + len/100 * 50)); 
 
    } 
 

 
    // Return this calculation for everything else. 
 
    return Math.round((len + len/100 * 30)); 
 
} 
 

 
function test() { 
 
    var out = document.getElementById("out"); 
 
    var text = ""; 
 

 
    for (var i = 0; i < 100; i += 3) { 
 
    text += i + ": " + getTextSpace(i) + "\n"; 
 
    } 
 
    out.innerHTML = text; 
 
} 
 

 
test();
<pre id="out"></pre>

1

Ramda功能非常强大,这意味着它的最佳用途是使用尽可能多的声明式和纯函数(泛型函数,可以在许多地方使用,而不仅仅是代码)。我的建议是这样的代码:

var getTextSpace = function (len) { 
    var conds = [ 
     {range: [1, 4], result: 10}, 
     {range: [5, 5], result: 14}, 
     {range: [6, 6], result: 16}, 
     {range: [7, 7], result: 18}, 
     {range: [8, 10], result: 20}, 
     {range: [11, 11], result: 22}, 
     {range: [12, 12], result: 24}, 
     {range: [13, 15], result: 26}, 
     {range: [16, 16], result: 28}, 
     {range: [17, 20], result: 32}, 
     {range: [21, 34], result: len * 2}, // You wrote tlength * 2 but it's not defined yet so I asumed you ment len * 2 
     {range: [35, 80], result: Math.round((len + len/100 * 50))} 
    ]; 

    var test = function (obj) { 
    var rangeLens = R.lensProp('range'); 
    var range = R.view(rangeLens, obj); 

    var lte = R.curry(R.lte)(range[0]); 
    var gte = R.curry(R.gte)(range[1]); 
    return R.both(lte, gte)(len); 
    } 

    var resultLens = R.lensProp('result'); 
    var getResult = R.curry(R.view)(resultLens); 

    var chosen = R.find(test)(conds); 
    var defIfNotFound = R.defaultTo({result: Math.round((len + len/100 * 30))}); 

    return getResult(defIfNotFound(chosen)); 

}; 

我想给每个功能解释做了什么名字,并把它们分解成许多部分,这使得它像是在读一个句子

0

如果你想要一个香草JS解决方案,这也许是另一种选择。

const isBetween = x => (s, e) => 
(Number(s) <= Number(x) && Number(x) <= Number(e)) 
? true : false 

const getTextSpace = len => { 
    const lenIsBetween = isBetween(len) 
    return lenIsBetween(1,4)? 10 
    : lenIsBetween(5, 5) ? 14 
    : lenIsBetween(6, 6) ? 16 
    : lenIsBetween(7, 7) ? 18 
    : lenIsBetween(8, 10) ? 20 
    : lenIsBetween(11, 11) ? 22 
    : lenIsBetween(12, 12) ? 24 
    : lenIsBetween(13, 15) ? 26 
    : lenIsBetween(16, 16) ? 28 
    : lenIsBetween(17, 20) ? 32 
    : lenIsBetween(21, 34) ? len * 2 
    : lenIsBetween(35, 80) ? Math.round((len + len/100 * 50)) 
    : Math.round((len + len/100 * 30)) 
}