如何使这段代码更具功能性和可读性?
how to make this code more functional and readable?
如何使这些 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 )})
也许switch
是另一种选择。有一个 post with quit 类似的话题。
看对了here.
您可以使用 switch 语句来避免所有 else 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;
}
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>
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)]
]);
}());
(原来的情况好像有bug:
} else if (len >= 21 && len <= 34) {
tlength = tlength * 2;
我认为是指
} else if (len >= 21 && len <= 34) {
tlength = len * 2;
我在这里编写了等效代码。)
您可以在 Ramda REPL.
上看到实际效果
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));
};
我试着给每个函数起一个名字来解释它的作用,并将它们分成许多部分,这使得它几乎就像在读一个句子
如果你想要一个普通的 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))
}
如何使这些 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 )})
也许switch
是另一种选择。有一个 post with quit 类似的话题。
看对了here.
您可以使用 switch 语句来避免所有 else 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;
}
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>
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)]
]);
}());
(原来的情况好像有bug:
} else if (len >= 21 && len <= 34) {
tlength = tlength * 2;
我认为是指
} else if (len >= 21 && len <= 34) {
tlength = len * 2;
我在这里编写了等效代码。)
您可以在 Ramda REPL.
上看到实际效果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));
};
我试着给每个函数起一个名字来解释它的作用,并将它们分成许多部分,这使得它几乎就像在读一个句子
如果你想要一个普通的 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))
}