按日期过滤嵌套数组

filtering nested arrays by date

我有一个包含 273 个数组的数组,每个数组都包含有关常规赛季 NFL 橄榄球比赛的数据。数组中的数据条目之一是比赛发生的日期。我正在尝试将我的数组过滤为包含特定一周内所有游戏的子数组。

换句话说,我想以 17 个数组结束,每个数组代表 NFL 赛季的一周。

我的数组看起来像这样 ["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);
    }
 }

这很好用,但是我将不得不为本赛季的所有 17 周硬编码一个 if 语句。

谁能想出一种方法来简化我的函数,以便我可以循环播放整个赛季的几周?

您需要创建一个包含初始数组中所有星期的新数组,因为您的星期都在同一年,您可以使用一年中的星期数来确定它们。 此代码将帮助您找出周数

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 周后的最终结果。

您需要循环您的初始数组并根据您的周数数组将其排序为最终数组。

上次更新/使用 Lodash 的最简单解决方案

使用 Lodash(如 avinash 所述)和 moments 只会是:

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"]
  ]; 

会return:

['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"]]]'