#javascript #reactjs #momentjs
Вопрос:
У меня есть массив из 273 массивов, каждый из которых содержит данные о футбольном матче регулярного чемпионата НФЛ. Одной из записей данных в массиве является дата начала игры. Я пытаюсь отфильтровать свой массив в поддиапазоны, содержащие все игры за определенную неделю.
Другими словами, я хочу, чтобы в итоге получилось 17 массивов, каждый из которых представляет неделю сезона НФЛ.
Мои массивы выглядят так ["2021-09-09", "DAL", "TB", ".55", .".45"]
.
Я могу использовать momentjs и написать функцию, которая проверяет, находится ли дата в массиве между двумя указанными датами.
for(const element of data){
if(moment(element[0]).isBetween("2021-09-08", "2021-09-14")){
weekOneArray.push(element);
}
}
Это прекрасно работает, однако мне придется жестко if
закодировать заявление на все 17 недель сезона.
Кто — нибудь может придумать способ упростить мою функцию, чтобы я мог переключаться на недели сезона?
Комментарии:
1. Используйте moment().unix (), чтобы получить метку времени Unix, которая представляет собой число. Затем вы можете использовать его для сортировки массива.
2. Не нужно использовать момент; просто используйте
element[0] > startDay amp;amp; element[0] < endDay
, и даты в формате гггг-ММ-дд будут сортироваться естественным образом.3. @HereticMonkey Разве мне все еще не нужно будет жестко указать дату начала и окончания?
4. Не можете ли вы сгенерировать все даты недели для сезона, а затем отправить свои данные на основе этих дат?
5.
moment(...).week()
иlodash.groupBy()
может сделать его чистым и понятным
Ответ №1:
Последнее обновление / Самое простое решение с Lodash
С Lodash (как упоминал авинаш) и моментами это было бы только:
const sortGamesAlt = (arrayOfGames) => {
return groupBy(arrayOfGames, (game) =>
moment(game[0]).isoWeekday(1)
);
};
Обновленный
Вы можете проверить этот код и настроить его в соответствии с вашими потребностями: https://codesandbox.io/s/crazy-mestorf-6yivl
После тестирования предыдущего кода я заметил некоторые детали, он может работать с этим:
const sortGames = (arrayOfGames) => {
const sortedGames = {};
arrayOfGames.forEach((game) => {
const startDate = moment(game[0]).isoWeekDay(1); // startOfWeek on Monday
sortedGames[startDate] = sortedGames[startDate]
? [...sortedGames[startDate], game]
: [game];
});
const sortedInfo = Object.entries(sortedGames).sort(
(a, b) => new Date(a[0]) - new Date(b[0])
);
return sortedInfo;
};
Получение:
const arrayOfGames = [
["2021-09-09", "DAL", "TB", ".55", ".45"],
["2021-10-09", "X", "Y", ".55", ".45"],
["2021-11-09", "Z", "A", ".55", ".45"],
["2021-09-12", "B", "C", ".55", ".45"],
["2021-09-10", "D", "E", ".55", ".45"]
];
Это вернется:
['Mon Nov 08 2021 00:00:00 GMT-0300', ['2021-11-09', 'Z', 'A', '.55', '.45']]
['Mon Oct 04 2021 00:00:00 GMT-0300', ['2021-10-09', 'X', 'Y', '.55', '.45']]
['Mon Sep 06 2021 01:00:00 GMT-0300', ['2021-09-09', 'DAL', 'TB', '.55', '.45'], ['2021-09-10', 'D', 'E', '.55', '.45'], '2021-09-12', 'B', 'C', '.55', '.45']]
СТАРАЯ / Краткая идея
Вы можете сделать что-то вроде этого:
const arrayOfGames = [["2021-09-09", "DAL", "TB", ".55", ".45"], ["2021-10-09", "X", "Y", ".55", ".45"], ["2021-11-09", "Z", "A", ".55", ".45"], ["2021-09-12", "B", "C", ".55", ".45"]] // it'll have all your arrays: ["2021-09-09", "DAL", "TB", ".55", .".45"]
const sortedGames = {};
arrayOfGames.forEach(game => {
// startOfWeek returns Sunday, so start on Monday if you add one day
const startDate = moment(game[0]).startOf('week').add(1, 'days')
// endOfWeek returns Saturday, so finish on Sunday if you add one day
const endDate = moment(game[0]).endOf('week').add(1, 'days')
// Insert with the other games or JUST define new array only with this game
sortedGames[startDate] = sortedGames[startDate] ? [...sortedGames[startDate], game] : [game]
})
Object
// return an array of [startDateOfWeek, arrayOfGamesOfThatWeek]
.entries(sortedGames)
// sort the array based on the startDate
.sort((a, b) => new Date(b[0]) - new Date(a[0]))
// Just return the array of games already sorted (you can also return the date if you want and ignore this line
.map(a => a[1])
// Returns [[["2021-11-09","Z","A",".55",".45"]],[["2021-10-09","X","Y",".55",".45"]],[["2021-09-12","B","C",".55",".45"]],[["2021-09-09","DAL","TB",".55",".45"]]]'
Ответ №2:
Вам нужно создать новый массив со всеми неделями из вашего исходного массива, поскольку все ваши недели относятся к одному и тому же году, вы можете использовать номер недели в году для их определения. Этот код поможет вам узнать номер недели
currentdate = new Date();
var oneJan = new Date(currentdate.getFullYear(),0,1);
var numberOfDays = Math.floor((currentdate - oneJan) / (24 * 60 * 60 * 1000));
var result = Math.ceil(( currentdate.getDay() 1 numberOfDays) / 7);
После этого вам нужно создать еще один массив, который будет вашим конечным результатом через 17 недель.
Вам нужно зациклить свой начальный массив и отсортировать его до конечного массива в соответствии с вашим массивом номеров недель.