重构具有多个else-if块的函数



我有以下函数,可以根据月份设置日期点。但我正在对价值观进行严格编码。我想重新考虑函数,并删除多余的else-if块。正如我们所看到的,当天数减少一定值时,会扣n-1分。那么,我该如何重构它呢?

points = {}
function calcPointsForDates(createdTime) {
let today = new Date()
let Y = today.getFullYear()
let M = today.getMonth()
let T = today.getDate()
let monthAgo = days => new Date(Y, M, T - days).getTime()
if (createdTime > monthAgo(30)) {
points.date = 2
} else if (createdTime < monthAgo(180)) {
points.date = -5
} else if (createdTime < monthAgo(90)) {
points.date = -4
} else if (createdTime < monthAgo(60)) {
points.date = -3
} else if (createdTime < monthAgo(30)) {
points.date = -2
}
}
calcPointsForDates(post.created.getTime())

考虑一个点对象,其属性是点的中断值,可用于实现与if.else块相同的逻辑,例如

let days2points = {'30': 2, '60': -2, '90': -3, '180': -4, '1e10': -5}; 

该值是通过循环键来找到第一个天数(diff(小于键的值。然后用于返回值,因此其中diff<30返回2,其中diff<60返回-2等。值"1e10"本质上代表无穷大,它可能被设置为Number.MAX_SAFE_INTEGER(9007199254740991天或约24.6万亿年前(。

因此,获取今天和createdDate之间的天数差异,找到相关密钥并返回积分,例如

function getPoints(createdTime) {
// Create a points object for points related to days ago
let days2points = {'30': 2, '60': -2, '90': -3, '180': -4, '1e10': -5}; 
// Get the number of days between today and createdTime
let diff = (new Date().setHours(0,0,0,0) - createdTime) / 8.64e7;
// Find the relevant value in the points object
let key = Object.keys(days2points).find(daysAgo => diff < daysAgo);
// Debug
console.log('Days ago: ' + diff + ' Value: ' + days2points[key]);
// Return the value
return days2points[key];
} 
// Examples
let d = new Date();
let [Y, M, D] = [d.getFullYear(), d.getMonth(), d.getDate()];
[ d,                        // today
new Date(Y, M, D -   3),  //   3 days ago
new Date(Y, M, D -  30),  //  30 days ago
new Date(Y, M, D -  33),  //  33 days ago
new Date(Y, M, D -  63),  //  63 days ago
new Date(Y, M, D -  93),  //  93 days ago
new Date(Y, M, D - 183)   // 183 days ago
].forEach(d => 
console.log(d.toDateString() + ' => ' + getPoints(d))
);

上面使用<进行比较,因此断点不包括在内,30天前返回-2。如果它们应该包含,则进行比较<=或在断点上加1。

注意事项

计算diff的方法是近似的,有更好的方法。

Object.keys中的对象属性不需要与用于创建days2points的对象文字的顺序相同,因此在迭代它们之前,应严格对它们进行排序。

您可以将限制和日期点添加到数组中,并从最低到最高迭代该数组。如果满足限制条件,则返回相应的日期点。如果不满足任何条件,则返回默认值。

const 
datePoints = [
[180, -5],
[90, -4],
[60, -3],
[30, -2]
],
defaultPoints = 2;
function daysAgo(d) {
const now = new Date();
return new Date(now.getFullYear(), now.getMonth(), now.getDay() - d);
}
function getDatePoints(createdTime) {
for (let d of datePoints) {
if (createdTime < daysAgo(d[0]))
return d[1];
}

return defaultPoints;
}
for (let i = 1; i < 200; i+= 10)
console.log(i, daysAgo(i).toISOString(), getDatePoints(daysAgo(i)));

相关内容

  • 没有找到相关文章

最新更新