简体   繁体   English

javascript 中最频繁的工作日问题

[英]most-frequent-weekdays problem in javascript

Doing the best research, I couldn't find the answer in JavaScript, But I found this solution that works perfectly in python做了最好的研究,我在 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))

Now trying to convert this into JavaScript, you need to know python (I know how to deal with python) the best thing I come up with现在尝试将其转换为 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;
};

Now this works in JS, however when I try to use the function I built mostFrequentDays(212) I don't get the expected output现在这在 JS 中有效,但是当我尝试使用 function 时,我构建了mostFrequentDays(212)我没有得到预期的 output

**You are given a year as an integer. Return the most frequent day(s) of the week in that year. **给定的年份为 integer。返回那一年中出现频率最高的一周中的一天。 The resulting list of days should be sorted by the order of days in week starting from Monday (eg ['Monday', 'Tuesday']).生成的天数列表应按从星期一开始的一周中的天数排序(例如 ['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"]);
});

A lot of them works when I convert the python code to JS except the last one because the JS Date doesn't work on year 212当我将 python 代码转换为 JS 时,它们中的很多都起作用,除了最后一个,因为 JS 日期在212 年不起作用

Please help me make a function that can pass all the tests, there are a lot of python versions of the solution but the one I used is the easy one, and in python, that code works because the DateTime in python work on a date like 212. Or maybe if you know a better version that's not originally from python, how would you implement a solution for JS请帮助我制作一个可以通过所有测试的 function,解决方案有很多 python 版本,但我使用的是简单的版本,在 python 中,该代码有效,因为 python 中的 DateTime 工作日期类似于212. 或者如果你知道一个更好的版本不是最初来自 python,你将如何实现 JS 的解决方案

Thank you, Best regards.谢谢您最好的问候。

You need to define "doesn't work".您需要定义“不起作用”。

A non–leap year has 365 days, which is 52 weeks plus one day.平年有 365 天,即 52 周加一天。 So whichever day is the first day of the year will have 53 occurrences and all the others will have 52. So the most frequent is just the weekday of 1 January.因此,无论哪一天是一年中的第一天,都会出现 53 次,而其他所有天都会出现 52 次。所以最频繁的只是 1 月 1 日这个工作日。

For a leap year, the first and second day will have 53 occurrences and the others 52. eg 1 Jan 2018 was Monday, as was 31 December, so there were 53 Mondays and 52 of the others.对于闰年,第一天和第二天将出现 53 次,其他日期为 52 次。例如,2018 年 1 月 1 日是星期一,12 月 31 日是星期一,因此有 53 个星期一和 52 个其他星期一。 1 Jan 2020 was Wednesday and a leap year, 31 Dec was Thursday so 53 Wednesdays and Thursdays and 52 of the rest. 2020 年 1 月 1 日是星期三和闰年,12 月 31 日是星期四,所以 53 个星期三和星期四以及 rest 中的 52 个。

Of course a random range of dates will make life a little more difficult.当然,随机的日期范围会让生活变得更加困难。

A function to implement the above is:一个 function 来实现上面的是:

 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)}` ));

Another algorithm (which is what the PHP code is doing) is to check if 1 Jan and 31 Dec are the same day.另一种算法(这是 PHP 代码所做的)是检查 1 月 1 日和 12 月 31 日是否是同一天。 If they are, return that day.如果是,当天返回。 If not, return both days.如果没有,请两天返回。

The only sorting that's required is where a leap year starts on Sunday.唯一需要的排序是闰年从星期日开始。 The default return is [Sunday, Monday] but the requirement is for [Monday, Sunday] in that particular case.默认返回是 [Sunday, Monday] 但在特定情况下要求是 [Monday, Sunday]。

So if 1 Jan is a Sunday (day 0) reverse the day list, eg因此,如果 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)}` ));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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