繁体   English   中英

如何降低该函数的圈复杂度?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM