javascriptfunctional-programmingramda.js

how to make this code more functional and readable?


How to make those javascript statements to look more readable. Could functional library ramda.js be used to make this code look better?

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;
    };

Thank you in advance.

Maybe it is possible to do something that will allow this ?

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

Solution

  • Ramda might help a bit. But the main thing is to structure your ranges in a readable manner. The code below assumes that the input values are integers and you don't need to test other numeric types. Those could be done, but then you'd need something more sophisticated than the simple between here. You'd need either multiple functions or a way to configure the one to determine whether each of the beginning and the end are inclusive or exclusive.

    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)]
      ]);
    }());
    

    (There seems to bug in the original case:

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

    which I assume meant

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

    and I coded the equivalent here.)

    You can see this in action on the Ramda REPL.