javascript 中最常见的工作日问题
most-frequent-weekdays problem in javascript
尽最大努力,我无法在 JavaScript 中找到答案,
但我发现这个解决方案在 python
中完美运行
import datetime
def most_frequent_days(year):
days = ('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday')
most = sorted(list(set([datetime.date(year, 1, 1).weekday() ,datetime.date(year, 12, 31).weekday()])))
return [days[i] for i in most]
print(most_frequent_days(212))
现在想把它转换成JavaScript,你需要知道python(我知道如何处理python)我想出的最好的办法
const mostFrequentDays = year => {
function getDayOfWeek(date) {
const dayOfWeek = new Date(date).getDay();
return isNaN(dayOfWeek) ? null :
['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'][dayOfWeek];
}
//let days = [ 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday' ]
let most = [getDayOfWeek(`${year}-1-1`), getDayOfWeek(`${year}-12-31`)].sort()
let mySet = [...new Set(most)]
//let sorted = mySet;
let i = 0;
let data = [];
while (i < mySet.length) {
data = [ ...data, mySet[i] ]
i++;
}
return data;
};
现在这在 JS 中有效,但是当我尝试使用我构建的函数时
mostFrequentDays(212)
我没有得到预期的输出
**给你一个整数年。 Return 那一年中一周中出现频率最高的一天。生成的天数列表应按从星期一开始的一周中的天数排序(例如 ['Monday'、'Tuesday'])。 **
Tests
it("should handle basic tests", () => {
assert.deepEqual(mostFrequentDays(2427), ["Friday"]);
assert.deepEqual(mostFrequentDays(2185), ["Saturday"]);
assert.deepEqual(mostFrequentDays(1084), ["Tuesday", "Wednesday"]);
assert.deepEqual(mostFrequentDays(1167), ["Sunday"]);
assert.deepEqual(mostFrequentDays(1216), ["Friday", "Saturday"]);
assert.deepEqual(mostFrequentDays(1492), ["Friday", "Saturday"]);
assert.deepEqual(mostFrequentDays(1770), ["Monday"]);
assert.deepEqual(mostFrequentDays(1785), ["Saturday"]);
assert.deepEqual(mostFrequentDays(212), ["Wednesday", "Thursday"]);
});
当我将 python 代码转换为 JS 时,除了最后一个代码,它们中的很多都有效,因为 JS 日期在 212 年 [=16 时不起作用=]
请帮我做一个可以通过所有测试的函数,有很多 python 版本的解决方案,但我使用的是简单的,在 python 中,该代码有效,因为 python 中的 DateTime 在 212 这样的日期工作。
或者如果你知道一个更好的版本不是最初来自 python,你将如何实现 JS
的解决方案
谢谢,
最好的问候。
您需要定义“不起作用”。
平年有 365 天,也就是 52 周加一天。因此,无论哪一天是一年中的第一天,都会出现 53 次,其他所有天都会出现 52 次。所以最频繁的只是 1 月 1 日这个工作日。
对于闰年,第一天和第二天将出现 53 次,其他日期为 52 次。例如2018 年 1 月 1 日是星期一,12 月 31 日也是,所以有 53 个星期一和 52 个其他星期一。 2020 年 1 月 1 日是星期三,闰年,12 月 31 日是星期四,所以 53 个星期三和星期四,其余 52 个。
当然,随机范围的日期会让生活变得更加困难。
实现上述的一个函数是:
function mostFrequentDaysOfYear(year = new Date().getFullYear()) {
// 1 Jan
let d = new Date(year, 0);
// Weekday name for 1 Jan
let mostFrequent = [d.toLocaleString('en',{weekday:'long'})];
let isLeap = new Date(year, 1, 29).getDate() == 29;
// If leap year, add next day's name too
if (isLeap) {
d.setDate(d.getDate() + 1);
mostFrequent.push(d.toLocaleString('en',{weekday:'long'}))
}
return mostFrequent;
}
// Examples
[2018, 2020, 2022, 212].forEach(year => console.log(
`${year}: ${mostFrequentDaysOfYear(year)}`
));
另一种算法(PHP 代码所做的)是检查 1 月 1 日和 12 月 31 日是否是同一天。如果是,那一天 return。如果没有,return 这两天。
唯一需要的排序是闰年从星期日开始。默认 return 是 [Sunday, Monday] 但在这种情况下要求是 [Monday, Sunday]。
因此,如果 1 月 1 日是星期日(第 0 天),则反转日期列表,例如
function mostFrequentDaysOfYear(year = new Date().getFullYear()) {
let dayName = d => d.toLocaleString('en',{weekday:'long'});
// 1 Jan
let d = new Date(year, 0, 1);
let d0 = dayName(d);
// 31 Dec
let d1 = dayName(new Date(year, 11, 31));
let result = d0 == d1? [d0] : [d0, d1];
// If d0 is Sunday, reverse result
return d.getDay()? result : result.reverse();
}
[2427, // Friday
2185, // Saturday
1084, // Tuesday, Wednesday
1167, // Sunday
1216, // Friday, Saturday
1492, // Friday, Saturday
1770, // Monday
1785, // Saturday
2040, // Monday, Sunday - leap year starting on Sun
212 // Wednesday, Thursday
].forEach(year => console.log(
`${year}: ${mostFrequentDaysOfYear(year)}`
));
尽最大努力,我无法在 JavaScript 中找到答案, 但我发现这个解决方案在 python
中完美运行import datetime
def most_frequent_days(year):
days = ('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday')
most = sorted(list(set([datetime.date(year, 1, 1).weekday() ,datetime.date(year, 12, 31).weekday()])))
return [days[i] for i in most]
print(most_frequent_days(212))
现在想把它转换成JavaScript,你需要知道python(我知道如何处理python)我想出的最好的办法
const mostFrequentDays = year => {
function getDayOfWeek(date) {
const dayOfWeek = new Date(date).getDay();
return isNaN(dayOfWeek) ? null :
['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'][dayOfWeek];
}
//let days = [ 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday' ]
let most = [getDayOfWeek(`${year}-1-1`), getDayOfWeek(`${year}-12-31`)].sort()
let mySet = [...new Set(most)]
//let sorted = mySet;
let i = 0;
let data = [];
while (i < mySet.length) {
data = [ ...data, mySet[i] ]
i++;
}
return data;
};
现在这在 JS 中有效,但是当我尝试使用我构建的函数时
mostFrequentDays(212)
我没有得到预期的输出
**给你一个整数年。 Return 那一年中一周中出现频率最高的一天。生成的天数列表应按从星期一开始的一周中的天数排序(例如 ['Monday'、'Tuesday'])。 **
Tests
it("should handle basic tests", () => {
assert.deepEqual(mostFrequentDays(2427), ["Friday"]);
assert.deepEqual(mostFrequentDays(2185), ["Saturday"]);
assert.deepEqual(mostFrequentDays(1084), ["Tuesday", "Wednesday"]);
assert.deepEqual(mostFrequentDays(1167), ["Sunday"]);
assert.deepEqual(mostFrequentDays(1216), ["Friday", "Saturday"]);
assert.deepEqual(mostFrequentDays(1492), ["Friday", "Saturday"]);
assert.deepEqual(mostFrequentDays(1770), ["Monday"]);
assert.deepEqual(mostFrequentDays(1785), ["Saturday"]);
assert.deepEqual(mostFrequentDays(212), ["Wednesday", "Thursday"]);
});
当我将 python 代码转换为 JS 时,除了最后一个代码,它们中的很多都有效,因为 JS 日期在 212 年 [=16 时不起作用=]
请帮我做一个可以通过所有测试的函数,有很多 python 版本的解决方案,但我使用的是简单的,在 python 中,该代码有效,因为 python 中的 DateTime 在 212 这样的日期工作。 或者如果你知道一个更好的版本不是最初来自 python,你将如何实现 JS
的解决方案谢谢, 最好的问候。
您需要定义“不起作用”。
平年有 365 天,也就是 52 周加一天。因此,无论哪一天是一年中的第一天,都会出现 53 次,其他所有天都会出现 52 次。所以最频繁的只是 1 月 1 日这个工作日。
对于闰年,第一天和第二天将出现 53 次,其他日期为 52 次。例如2018 年 1 月 1 日是星期一,12 月 31 日也是,所以有 53 个星期一和 52 个其他星期一。 2020 年 1 月 1 日是星期三,闰年,12 月 31 日是星期四,所以 53 个星期三和星期四,其余 52 个。
当然,随机范围的日期会让生活变得更加困难。
实现上述的一个函数是:
function mostFrequentDaysOfYear(year = new Date().getFullYear()) {
// 1 Jan
let d = new Date(year, 0);
// Weekday name for 1 Jan
let mostFrequent = [d.toLocaleString('en',{weekday:'long'})];
let isLeap = new Date(year, 1, 29).getDate() == 29;
// If leap year, add next day's name too
if (isLeap) {
d.setDate(d.getDate() + 1);
mostFrequent.push(d.toLocaleString('en',{weekday:'long'}))
}
return mostFrequent;
}
// Examples
[2018, 2020, 2022, 212].forEach(year => console.log(
`${year}: ${mostFrequentDaysOfYear(year)}`
));
另一种算法(PHP 代码所做的)是检查 1 月 1 日和 12 月 31 日是否是同一天。如果是,那一天 return。如果没有,return 这两天。
唯一需要的排序是闰年从星期日开始。默认 return 是 [Sunday, Monday] 但在这种情况下要求是 [Monday, Sunday]。
因此,如果 1 月 1 日是星期日(第 0 天),则反转日期列表,例如
function mostFrequentDaysOfYear(year = new Date().getFullYear()) {
let dayName = d => d.toLocaleString('en',{weekday:'long'});
// 1 Jan
let d = new Date(year, 0, 1);
let d0 = dayName(d);
// 31 Dec
let d1 = dayName(new Date(year, 11, 31));
let result = d0 == d1? [d0] : [d0, d1];
// If d0 is Sunday, reverse result
return d.getDay()? result : result.reverse();
}
[2427, // Friday
2185, // Saturday
1084, // Tuesday, Wednesday
1167, // Sunday
1216, // Friday, Saturday
1492, // Friday, Saturday
1770, // Monday
1785, // Saturday
2040, // Monday, Sunday - leap year starting on Sun
212 // Wednesday, Thursday
].forEach(year => console.log(
`${year}: ${mostFrequentDaysOfYear(year)}`
));