在数组中查找最近的日期

时间:2019-02-15 00:19:45

标签: javascript html arrays function date

我试图在具有不同日期的对象数组中查找最高日期,这些日期将归因于每个对象。只要日期高于1970年1月1日,该代码就可以很好地工作,但是在此日期之前的任何日期都会导致错误。如何通过明显保持相同日期来解决此问题?我知道我可以在所有日期上使用get(Time),但是有什么办法吗?谢谢。

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

6 个答案:

答案 0 :(得分:1)

代替比较日期,您可以比较字符串并使用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 });

答案 1 :(得分:0)

如果您在日期上使用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)

答案 2 :(得分:0)

您可以预先指定第一人称的日期来进行比较。

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)

您可以执行此操作。我简化了逻辑。您也可以像其他人建议的那样使用sort()。

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

答案 4 :(得分:0)

大多数情况下,使用>强制数字,但是与数字 null 进行比较时,其值为0,因此负数小于 null

因此只需通过将 highDateSoFar 初始化为其他某个值(例如-Infinity或数组中的第一个日期)或测试其为 null 来避免进行比较,例如

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 引用相同的Date对象时,表达式playerData[i].date === highDateSoFar才为true。功能的逻辑。

您也可以为此使用 reduce

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

答案 5 :(得分:0)

我经常发现通过上移一个或两个抽象层来解决问题更容易。如果我们要查找具有最高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,但是很难知道还要做什么。如果很重要,您可以随时添加默认值参数。