代码之家  ›  专栏  ›  技术社区  ›  Harper Creek

在数组中查找最近的日期

  •  0
  • Harper Creek  · 技术社区  · 7 年前

    我试图在一系列具有不同日期的对象中找到最高日期,这些日期将归属于每个对象。只要日期在1970年1月1日以上,代码就工作得很好,但在此之前的任何日期都会导致错误。我怎么能用同样的日期来解决呢?我知道我可以利用所有的日期(时间),但有什么办法吗?谢谢。

    var playerData = [
        {name: "John"},
        {name: "Bill"},
        {name: "Bob"},
        {name: "Jim"},
        
    ];
        
    var dateOne = new Date(1940,02,05);
    var dateTwo = new Date(1950, 06,18);
    var dateThree = new Date(1650,07,12);
    var dateFour = new Date(1300, 03,25);
        
    playerData[0].date = dateOne;
    playerData[1].date = dateTwo;
    playerData[2].date = dateThree;
    playerData[3].date = dateFour;
    
    function findHighDate() {
        var highDateSoFar = null;
        var result;
        for (var i = 0; i < playerData.length; i++) {
            if (playerData[i].date > highDateSoFar) {
                result = playerData[i];
                highDateSoFar = playerData[i].date;
            }
            else if (playerData[i].date === highDateSoFar) {	
                result = 'equal';
            
        }
        }
        return result;
    }
        
    var highPlayer = findHighDate();
    var highPlayerName = highPlayer.name;
    var highPlayerIndex = playerData.indexOf(highPlayer);
    var highPlayerDate = highPlayer.date;
    console.log({highPlayer},{highPlayerIndex},{highPlayerName},{highPlayerDate});
    5 回复  |  直到 7 年前
        1
  •  1
  •   jo_va    7 年前

    您可以比较字符串并使用 Array.sort 要按降序排列,请获取第一项:

    const playerData = [
      {name: "John", date: '1940-02-05' },
      {name: "Bill", date: '1950-06-18' },
      {name: "Bob", date: '1650-07-12' },
      {name: "Jim", date: '1300-03-25' },
    ];
    
    function findHighDate() {
      return playerData.sort((a, b) => b.date.localeCompare(a.date))[0];
    }
        
    const highPlayer = findHighDate();
    const highPlayerName = highPlayer.name;
    const highPlayerIndex = playerData.indexOf(highPlayer);
    const highPlayerDate = new Date(highPlayer.date);
    console.log({ highPlayer, highPlayerIndex, highPlayerName, highPlayerDate });

    或者你也可以坚持使用日期并使用 Date.getTime() 排序数组:

    const playerData = [
      {name: "John", date: new Date('1940-02-05') },
      {name: "Bill", date: new Date('1950-06-18') },
      {name: "Bob", date: new Date('1650-07-12') },
      {name: "Jim", date: new Date('1300-03-25') },
    ];
    
    function findHighDate() {
      return playerData.sort((a, b) => b.date.getTime() - a.date.getTime())[0];
    }
        
    const highPlayer = findHighDate();
    const highPlayerName = highPlayer.name;
    const highPlayerIndex = playerData.indexOf(highPlayer);
    const highPlayerDate = highPlayer.date;
    console.log({ highPlayer, highPlayerIndex, highPlayerName, highPlayerDate });

    正如@Scott Sauyet在下面的评论中指出的,使用 Array.sort 对你的场景来说可能是太过分了。

    你可以找到你的最高日期与多一点的代码和帮助 reduce :

    const playerData = [
      {name: "John", date: new Date('1940-02-05') },
      {name: "Bill", date: new Date('1950-06-18') },
      {name: "Bob", date: new Date('1650-07-12') },
      {name: "Jim", date: new Date('1300-03-25') },
    ];
    
    function findHighDate() {
      return playerData.reduce((highest, player) => {
        return highest.date.getTime() > player.date.getTime() ? highest : player;
      }, playerData[0]);
    }
        
    const highPlayer = findHighDate();
    const highPlayerName = highPlayer.name;
    const highPlayerIndex = playerData.indexOf(highPlayer);
    const highPlayerDate = highPlayer.date;
    console.log({ highPlayer, highPlayerIndex, highPlayerName, highPlayerDate });
        2
  •  0
  •   Badabomb    7 年前

    var playerData = [
        {name: "John"},
        {name: "Bill"},
        {name: "Bob"},
        {name: "Jim"},
    
    ];
    
    var dateOne = new Date(1940,02,05);
    var dateTwo = new Date(1950, 06,18);
    var dateThree = new Date(1650,07,12);
    var dateFour = new Date(1300, 03,25);
    
    playerData[0].date = dateOne;
    playerData[1].date = dateTwo;
    playerData[2].date = dateThree;
    playerData[3].date = dateFour;
    
    function findHighDate() {
        console.log(playerData);
        var highDateSoFar = playerData[0].date;
        var result = playerData[0];
        for (var i = 0; i < playerData.length; i++) {
            if (playerData[i].date > highDateSoFar) {
                result = playerData[i];
                highDateSoFar = playerData[i].date;
            }
            else if (playerData[i].date === highDateSoFar) {    
    
        }
        }
        return result;
    }
    
    var highPlayer = findHighDate();
    var highPlayerName = highPlayer.name;
    var highPlayerIndex = playerData.indexOf(highPlayer);
    var highPlayerDate = highPlayer.date;
    console.log({highPlayer},{highPlayerIndex},{highPlayerName},{highPlayerDate});
    
        3
  •  0
  •   Matt Way    7 年前

    如果你使用 getTime() 在日期上,1970年之前的数字将是负数,所以通常的数学比较很有效。下面我简单地按日期对你的播放器数据进行排序(最大值优先)。如果想要最高的,只需抓取数组中的第一项:

    var playerData = [
      {name: "John"},
      {name: "Bill"},
      {name: "Bob"},
      {name: "Jim"},   
    ]
        
    playerData[0].date = new Date(1940, 02, 05)
    playerData[1].date = new Date(1950, 06, 18)
    playerData[2].date = new Date(1650, 07, 12)
    playerData[3].date = new Date(1300, 03, 25)
    
    playerData.sort((a, b) => b.date.getTime() - a.date.getTime())
    
    console.log(playerData)
        4
  •  0
  •   dabishan    7 年前

    var playerData = [
        {name: "John"},
        {name: "Bill"},
        {name: "Bob"},
        {name: "Jim"},
        
    ];
        
    var dateOne = new Date(1940,02,05);
    var dateTwo = new Date(1950, 06,18);
    var dateThree = new Date(1650,07,12);
    var dateFour = new Date(1300, 03,25);
        
    playerData[0].date = dateOne;
    playerData[1].date = dateTwo;
    playerData[2].date = dateThree;
    playerData[3].date = dateFour;
    
    function playerWithHighestDate() {
    	// start by assuming player 0 is highest
        var winner = 0;
        
        // start at one as we dont need to compare with player 0
        for (var i = 1; i < playerData.length; i++) {
        		// compares players date
            if (playerData[i].date >= playerData[winner].date) {
                winner = i;
            }
        }
        
        // returns the winner index
        return winner;
    }
    
    // get index with highest date
    var highPlayerIndex = playerWithHighestDate();
    var highPlayer = playerData[highPlayerIndex];
    var highPlayerName = highPlayer.name;
    var highPlayerDate = highPlayer.date;
    console.log({highPlayer},{highPlayerIndex},{highPlayerName},{highPlayerDate});
        5
  •  0
  •   RobG    7 年前

    使用 > 因为与数字的共回归在大多数情况下都是有效的,然而当与数字进行比较时 计算结果为0,因此负数小于 .

    所以只要通过初始化 截止日期 或者测试它是否存在 无效的

    var playerData = [
        {name: "John", date: new Date(1940, 2,  5)},
        {name: "Bill", date: new Date(1950, 6, 18)},
        {name: "Bob",  date: new Date(1650, 7, 12)},
        {name: "Jim",  date: new Date(1300, 3, 25)},
    ];
    
    function findHighDate(data) {
      var highDateSoFar = null; 
      var result;
      
      for (var i=0; i < data.length; i++) {
    
        if (highDateSoFar === null || data[i].date > highDateSoFar) {
          result = data[i];
          highDateSoFar = data[i].date;
        }
      }
      return result ;
    }
    
    console.log( findHighDate(playerData) );

    还有表达式 playerData[i].date === highDateSoFar 截止日期 引用相同的日期对象,这在函数的逻辑中不可能是真的。

    减少 对于这一点:

    var playerData = [
      {name: "John", date: new Date(1940, 2,  5)},
      {name: "Bill", date: new Date(1950, 6, 18)},
      {name: "Bob",  date: new Date(1650, 7, 12)},
      {name: "Jim",  date: new Date(1300, 3, 25)},
    ];
    
    function getHighest(data) {
      return data.reduce((acc, high) => {
         acc = high.date > acc.date? high : acc;
         return acc;
      }, {date:-Infinity});
    }
    
    console.log(getHighest(playerData));
        6
  •  0
  •   Scott Sauyet    7 年前

    我经常发现,通过提升一两个抽象层次来解决问题更容易。如果我们想找到具有最高date属性的对象,我可以先写一些东西,通过任何给定的属性找到最大值。但更好的是,我可以给它提供一个函数,并找到使函数最大化的值。事实证明,这和date一样容易写,而且它将寻找最大值的逻辑与选择date属性的普通逻辑分离开来。

    所以我们可以在这里写作

    const maximumBy = (fn) => (data) => 
      data.reduce((m, x) => fn(x) > fn(m) ? x : m, data[0])
    
    const findHighestPlayer = maximumBy(player => player.date)
    
    var playerData = [
        {name: "John", date: new Date(1940, 2,  5)},
        {name: "Bill", date: new Date(1950, 6, 18)},
        {name: "Bob",  date: new Date(1650, 7, 12)},
        {name: "Jim",  date: new Date(1300, 3, 25)},
    ];
    
    
    console.log(findHighestPlayer(playerData))

    请注意,如果数组为空,则返回 undefined ,但很难知道还能做什么。如果需要修复的话,您可以添加一个默认值参数。

    推荐文章