Mark Richman
Mark Richman

Reputation: 29710

Given an associative array of Date strings, find the next closest date

Given an associative array of Date strings, how do I find the next closest date on or after today?

UPDATE: What if this were an associative array? How do I return the key for the closest date?

var matchdays = {};

7386: "09/14/2010"
7387: "09/29/2010"
7388: "10/20/2010"
7389: "11/02/2010"
7390: "11/24/2010"
7391: "12/07/2010"
7392: "12/18/2010"

For example, I'd expect it to return 7392 because 12/18 is on or after today (12/14).

Upvotes: 1

Views: 2545

Answers (1)

Jeff B
Jeff B

Reputation: 30099

Sort your array, and then search until you find a date later than today. You could also do a binary search, or other fancy things depending on the size of your array and your performance requirements.

var today = new Date();

dateList.sort();

var nextLater = null;

for (var i = 0; i < dateList.length; i++) {
  if (dateList[i] > today) {
    nextLater = dateList[i];
    break;
  }
}

Update

Associative arrays are a bit trickier. You can sort the keys by the dates, and then do the same as above, or you could simply go through one at a time tracking the smallest positive offset from today. The former is like this:

// Function to get the keys
function keys(obj) {
    var keys = [];
    for (var key in obj) {
        keys.push(key);
    }
    return keys;
}

// Get the keys, then sort the keys by there associated date
var keys = keys(matchdays).sort(function(a, b) {
    var d1 = new Date(matchdays[a]);
    var d2 = new Date(matchdays[b]);

    return d1 - d2;
});

// Iterate through the keys, finding the key associated with the next date after today
var today = new Date();
var nextLater = null;

for (var i = 0; i < keys.length; i++) {
    var date = new Date(matchdays[keys[i]]);

    if (date > today) {
        nextLater = keys[i];
        break;
    }
}

alert(nextLater);

Sorting adds some redundancy as a brute force search is going to be O(n) and a best-case sort is going to be O(n) as well. So to brute force search, just:

// Function to get the keys
function keys(obj) {
    var keys = [];
    for (var key in obj) {
        keys.push(key);
    }
    return keys;
}

// Get the keys
var keys = keys(matchdays);

// Iterate through the keys, finding the key associated with the next date after today
var today = new Date();
var nextLater = null;
var min;

for (var i = 0; i < keys.length; i++) {
    var date = new Date(matchdays[keys[i]]);

    var diff = date - today;

    if (diff > 0 && (min == undefined || diff < min ) {
        min = diff
        nextLater = keys[i];
    }
}

alert(nextLater);

Upvotes: 2

Related Questions