[英]How to reduce the cyclomatic complexity of this function?
我有一个函数需要一个时间戳记的时间(例如1517073001
)并以“ 2小时前”之类的简单格式返回自那时以来经过的时间(而不是像“ 2小时31分钟15秒”之类的进一步冗长的1517073001
) 。
该函数按预期工作,但JSHint抱怨使用过多的语句(30),并且其循环复杂度过高(12)。 我想知道有什么办法可以改善这两个方面。
这是功能:
function msToTime(epoch) { var previous = new Date(epoch * 1000); var current = Math.floor(new Date().getTime()); var ms = current - previous; var years = parseInt((ms / (1000 * 60 * 60 * 24 * 30 * 12)).toFixed(20), 10); var months = parseInt((ms / (1000 * 60 * 60 * 24 * 30) % 12).toFixed(20), 10); var days = parseInt((ms / (1000 * 60 * 60 * 24) % 30).toFixed(20), 10); var hours = parseInt((ms / (1000 * 60 * 60) % 24).toFixed(20), 10); var minutes = parseInt(ms / (1000 * 60) % 60, 10); var seconds = parseInt(ms / 1000 % 60, 10); var formatted = ''; if (years > 0) { if (years > 1) { formatted = years + ' years ago'; } else { formatted = years + ' year ago'; } } else if (months > 0) { if (months > 1) { formatted = months + ' months ago'; } else { formatted = months + ' month ago'; } } else if (days > 0) { if (days > 1) { formatted = days + ' days ago'; } else { formatted = days + ' day ago'; } } else if (hours > 0) { if (hours > 1) { formatted = hours + ' hours ago'; } else { formatted = hours + ' hour ago'; } } else if (minutes > 0) { if (minutes > 1) { formatted = minutes + ' minutes ago'; } else { formatted = minutes + ' minute ago'; } } else { if (seconds > 1) { formatted = seconds + ' seconds ago'; } else { formatted = seconds + ' second ago'; } } return formatted; } var div = document.getElementById('time'); div.innerHTML = msToTime(1517073001);
<div id="time"></div>
先感谢您。 :)
针对div和模块操作进行了优化的另一个版本
function msToTime(epoch) {
var value = (Math.floor(new Date().getTime()) - new Date(epoch * 1000)) / 1000;
var time_factors = [['second', 60], ['minute', 60], ['hour', 24], ['day', 30], ['month', 12], ['year', NaN]];
for (factor of time_factors) {
if (value < factor[1] || isNaN(factor[1])) {
var t = Math.floor(value);
return t + ' ' + (t > 1 ? factor[0] + 's' : factor[0]) + ' ago';
}
value /= factor[1];
}
}
通过switch (true)
替换if...else if...else if...
,并将单数或复数形式的构建放入函数中:
function msToTime(epoch) { let previous = new Date(epoch * 1000); let current = Math.floor(new Date().getTime()); let ms = current - previous; let years = parseInt((ms / (1000 * 60 * 60 * 24 * 30 * 12)).toFixed(20), 10); let months = parseInt((ms / (1000 * 60 * 60 * 24 * 30) % 12).toFixed(20), 10); let days = parseInt((ms / (1000 * 60 * 60 * 24) % 30).toFixed(20), 10); let hours = parseInt((ms / (1000 * 60 * 60) % 24).toFixed(20), 10); let minutes = parseInt(ms / (1000 * 60) % 60, 10); let seconds = parseInt(ms / 1000 % 60, 10); let formatted = ''; function timeAgo(count, word) { return `${count} ${(count === 1 ? word : word + 's')} ago` } switch (true) { case years > 0: formatted = timeAgo(years, 'year') break case months > 0: formatted = timeAgo(months, 'month') break case days > 0: formatted = timeAgo(days, 'day') break case hours > 0: formatted = timeAgo(hours, 'hour') break case minutes > 0: formatted = timeAgo(minutes, 'minute') break default: formatted = timeAgo(seconds, 'second') } return formatted; } time.innerHTML = msToTime(1517073001);
<div id="time"></div>
将日期定义为数组并对其进行迭代,已使Cyclomatic复杂度数降至4(!),仅包含12条语句。
function msToTime(epoch) { var previous = new Date(epoch * 1000); var current = Math.floor(new Date().getTime()); var ms = current - previous; var formatted = ''; var completeDate = [ ['year', parseInt((ms / (1000 * 60 * 60 * 24 * 30 * 12)).toFixed(20), 10)], ['month', parseInt((ms / (1000 * 60 * 60 * 24 * 30) % 12).toFixed(20), 10)], ['day', parseInt((ms / (1000 * 60 * 60 * 24) % 30).toFixed(20), 10)], ['hour', parseInt((ms / (1000 * 60 * 60) % 24).toFixed(20), 10)], ['minute', parseInt(ms / (1000 * 60) % 60, 10)], ['second', parseInt(ms / 1000 % 60, 10)] ]; for (var i = 0; i < completeDate.length; i++) { var amount = completeDate[i][1]; if (amount > 0) { var unit = completeDate[i][0]; formatted = amount + ' ' + (amount > 1 ? unit + 's' : unit) + ' ago'; break; } } return formatted; } var div = document.getElementById('time'); div.innerHTML = msToTime(1517073001);
<div id="time"></div>
感谢@connexo,提供重要建议!
function msToTime (epoch) {
var previous = new Date(epoch * 1000);
var current = Math.floor(new Date().getTime());
var ms = current - previous;
var years = parseInt((ms / (1000 * 60 * 60 * 24 * 30 * 12)).toFixed(20), 10);
var months = parseInt((ms / (1000 * 60 * 60 * 24 * 30) % 12).toFixed(20), 10);
var days = parseInt((ms / (1000 * 60 * 60 * 24) % 30).toFixed(20), 10);
var hours = parseInt((ms / (1000 * 60 * 60) % 24).toFixed(20), 10);
var minutes = parseInt(ms / (1000 * 60) % 60, 10);
var seconds = parseInt(ms / 1000 % 60, 10);
var formatted = '';
if (years > 0) {
formatted = years > 1 ? years + ' years ago' : years + ' year ago';
} else if (months > 0) {
formatted = months > 1 ? ' months ago' : ' month ago';
} else if (days > 0) {
formatted = days > 1 ? ' days ago' : ' day ago';
} else if (hours > 0) {
formatted = hours > 1 ? ' hours ago' : ' hour ago';
} else if (minutes > 0) {
formatted = minutes > 1 ? ' minutes ago' : ' minute ago';
} else {
formatted = seconds > 1 ? ' seconds ago' : ' second ago';
}
return formatted;
}
var div = document.getElementById('time');
div.innerHTML = msToTime(1417073002);
我使用JS三元运算符来缩短您的代码。 希望能帮助到你。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.